Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 343
Bartek Avatar asked Aug 07 '18 11:08

Bartek


People also ask

How do you find the max number of a list in a stream?

Calling stream() method on the list to get a stream of values from the list. Calling mapToInt(value -> value) on the stream to get an Integer Stream. Calling max() method on the stream to get the max value. Calling orElseThrow() to throw an exception if no value is received from max()

How do I find the max date in a list of dates using Java?

stream() . map(u -> u. date) . max(Date::compareTo) .

How do you find the max element in an array using stream?

With the introduction of Stream with Java 8, we can convert the array into the corresponding type stream using the Arrays. stream() method. Then we can call the max() and min() method, which returns the maximum and minimum element of this stream as OptionalInt .


2 Answers

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.

like image 195
Peter Lawrey Avatar answered Nov 14 '22 22:11

Peter Lawrey


Having null values in the List and looking for the max value? Firstly get rid of the null values using Stream::filter. Then the job is easy:

LocalDate max = dates.stream()
                     .filter(Objects::nonNull)
                     .max(Comparator.naturalOrder()).get();

If you insist on using the Comparator only, use Comparator::nullsFirst instead:

LocalDate max = dates.stream().max(Comparator.nullsFirst(Comparator.naturalOrder())).get();
  • Comparator::nullsFirst returns a null-friendly comparator that considers null to be less than non-null.
  • Comparator::nullsLast returns a null-friendly comparator that considers null to be greater than non-null.
like image 30
Nikolas Charalambidis Avatar answered Nov 14 '22 22:11

Nikolas Charalambidis