Question: Having issues with comparing two products. I wish to compare the vintage (which is optional) attribute of each of them. But whenever this attribute is null, a NPE is thrown. I thought with Comparator.nullsLast(..) I can deal with null values... But it seems I either have a misunderstanding of how this works or there's something wrong with the code. What do I need to change to get this work null-friendly? 

```
@Override
public int compare(IProduct product1, IProduct product2) throws ProductComparisonException {

    Comparator<IShopProduct> comparator =
        Comparator.nullsLast(Comparator.comparing(IShopProduct::getVintage));

    return comparator.compare((IShopProduct)product1.getProvidedProductData(),
                              (IShopProduct)product2.getProvidedProductData());
}

```

Thanks in advance

Answer: 
It should be

```
Comparator<IShopProduct> comparator = 
            Comparator.comparing( IShopProduct::getVintage, 
                             Comparator.nullLast(naturalOrder()));

```

`Comparator.nullFirst()/nullLast()` consider null value being greater/smaller than nonNull object

**Edit**

This is implementation of Comparator.comparing():

```
public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
        Function<? super T, ? extends U> keyExtractor)
{
    Objects.requireNonNull(keyExtractor);
    return (Comparator<T> & Serializable)
        (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}

```

As you can see it calls `keyExtractor.apply(c1).compareTo()` so it will throw NPE if `keyExtractor.apply(c1)` is `null`

My suggested code using the following function:

```
public static <T, U> Comparator<T> comparing(
        Function<? super T, ? extends U> keyExtractor,
        Comparator<? super U> keyComparator)
{
    Objects.requireNonNull(keyExtractor);
    Objects.requireNonNull(keyComparator);
    return (Comparator<T> & Serializable)
        (c1, c2) -> keyComparator.compare(keyExtractor.apply(c1),
                                          keyExtractor.apply(c2));
}

```

Basically it will extracts the value, then pass the comparing values to `Comparator`.

The values will be passed to the `naturalOrder()` comparator which resolved to `value1.compareTo(value2)`. Normally it will throw NPE but we have wrapped it with `Comparator.nullLast` which have special `null` handler.
This overload of the [comparing](https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#comparing-java.util.function.Function-) method will throw an exception if the passed in key extractor function is `null` or the property extracted is `null`. Since, you mentioned the `vintage` property can be `null` at times then this is the cause of the NullPointerException.

An alternative, to overcome the problem is to use this comparator:

```
 Comparator<IShopProduct> comparator = 
      Comparator.comparing(IShopProduct::getVintage,
                Comparator.nullsLast(naturalOrder()));

```

The key extractor i.e `IShopProduct::getVintage` is the function used to extract the sort key.

The key comparator i.e. the `Comparator.nullsLast(Comparator.naturalOrder())` is used to compare the sort key.

`Comparator.naturalOrder()` here simply returns a comparator that compares `Comparable` objects in natural order.