Java Comparator with null fields

Sergio Lema :

I have a list of entities Entity with the fields id and createdDate. I want to sort them as following:

  • higher id first
  • if id null, most recent createdDate first

I've tried the following unsuccessfuly, as it throwns a NullPointerException when id is null

Comparator comp = Comparator
                .nullsFirst(Comparator.comparing(e -> ((Entity) e).getId()))
                .thenComparing(e -> ((Entity e).getCreatedDate())
                .reversed();
entities.stream().sorted(comp).findFirst();

For what I see, Comparator.nullsFirst handles when the entity is null, not when the field to be compared is null. How can I handle this situation?

michalk :

I think you are looking for comparator like this :

Comparator<MyClass> comparator = Comparator.comparing(MyClass::getId, Comparator.nullsLast(Comparator.reverseOrder()))
                .thenComparing(MyClass::getCreateDate);

The code to test it :

List<MyClass> list = new ArrayList<>();

list.add(new MyClass(null, LocalDate.now()));
list.add(new MyClass(4L, LocalDate.now()));
list.add(new MyClass(2L, LocalDate.now()));
list.add(new MyClass(4L, LocalDate.now().plusDays(1)));
list.add(new MyClass(null, LocalDate.now().plusDays(1)));

Comparator<MyClass> comparator = Comparator.comparing(MyClass::getId, Comparator.nullsLast(Comparator.reverseOrder()))
                .thenComparing(MyClass::getCreateDate);

list.stream().sorted(comparator).forEach(myClass -> System.out.println(myClass.id + " " + myClass.createDate));

The output is :

4 2019-06-14
4 2019-06-15
2 2019-06-14
null 2019-06-14
null 2019-06-15

If you want nulls to be first just change nullsLast to nullsFirst.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=120964&siteId=1