Java Comparator с пустыми полями - PullRequest
6 голосов
/ 14 июня 2019

У меня есть список сущностей Entity с полями id и createdDate. Я хочу отсортировать их следующим образом:

  • выше id первый
  • если id ноль, самый последний createdDate первый

Я пробовал следующее безуспешно, так как он выбрасывает NullPointerException, когда id равен нулю

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

Что я вижу, Comparator.nullsFirst обрабатывает, когда сущность равна нулю, а не когда сравниваемое поле равно нулю. Как я могу справиться с этой ситуацией?

Ответы [ 4 ]

5 голосов
/ 14 июня 2019

Я думаю, вы ищете компаратор, подобный этому:

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

Код для его проверки:

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));

Вывод:

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

Если вы хотите, чтобы nulls был первым, просто измените nullsLast на nullsFirst.

1 голос
/ 14 июня 2019

Используя ненулевой метод из класса Object, возможно, можно решить его.

Comparator comp = Comparator
            .nullsFirst(Comparator.comparing(e -> nonNull(((Entity) e).getId()))
            .thenComparing(e -> ((Entity e).getCreatedDate())
            .reversed();
entities.stream().filter(comp).findFirst();
1 голос
/ 14 июня 2019

Расширение комментария @ Мены:

java.util.Collections.sort(entities, new Comparator<Entity>(){
   @Override
   public int compare(Entity ent1, Entity ent2) {
     Object id1=ent1.getId();
     Object id2 = ent2.getId();
     if (id1!=null && id2!=null)
     {
       return id2.compareTo(id1);
     }
     else
     {
       Date d1 = ent1.getCreatedDate();
       Date d2 = ent2.getCreatedDate();
       return d2.compareTo(d1);
     }
   }
});
0 голосов
/ 14 июня 2019

Я не часто использую лямбды, но могу помочь вам с компаратором.

Comparator<Entity> cmp = new Comparator<Entity>() {

        @Override
        public int compare(Entity e1, Entity e2) {
            if(e1.id!=null && e2.id!=null){
                return e2.id - e1.id;
            }
            return e1.createdDate - e2.createdDate;
            //createdDate should be an Integer field otherwise convert it to integer somehow.
        }

    };
    //To use this comparator
    Collections.sort(your_list,cmp);
...