Search code examples
javalistjava-8java-streamcomparator

How to get max of dates list with stream, when having nulls in list


I have following code:

List<LocalDate> dates = Arrays.asList(null, null, 
    LocalDate.now(), LocalDate.now().minusDays(9));

LocalDate max = dates.stream()
    .max(Comparator.nullsLast(Comparator.naturalOrder())).get();

Which produce null pointer exception when I try to get the max, but when trying to get min it works ok. It seems unclear cause max takes Comparator which handles null values. How to sort such array with stream preserving null values.

By the way, I checked JavaDoc of max, which states:

@throws NullPointerException if the maximum element is null

EDIT:

LocalDate max = dates.stream()
    .max(Comparator.nullsLast(Comparator.naturalOrder())).orElse(null);

Throws null pointer as well.


Solution

  • If you expect the answer to be null because it contains one you can do your own reduction.

    List<LocalDate> dates = Arrays.asList(null, null,
            LocalDate.now(), LocalDate.now().minusDays(9));
    
    LocalDate max = dates.stream()
            .reduce(LocalDate.MIN,
                    BinaryOperator.maxBy(Comparator.nullsLast(Comparator.naturalOrder())));
    System.out.println(max);
    

    prints

    null
    

    NOTE: This is different in the sense that an empty list returns LocalDate.MIN.

    A less obvious option is to replace null with LocalDate.MAX assuming this is never used.

    LocalDate max = dates.stream()
            .map(d -> d == null ? LocalDate.MAX : d)
            .max(Comparator.naturalOrder())
            .map(d -> LocalDate.MAX.equals(d) ? null : d)
            .orElse(null);
    

    This returns null for an empty list.