具有空字段的Java比较器

Ser*_*ema 6 java sorting java-8 java-stream

我有一个Entity带有字段id和的实体列表createdDate。我想对它们进行如下排序:

  • 更高的id第一
  • 如果为idnull,则最新的createdDate优先

我尝试了以下不成功的方法,因为它抛出一个NullPointerExceptionwhen id为null

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

对于我所看到的,Comparator.nullsFirst当实体为null时进行处理,而不是在要比较的字段为null时进行处理。我该如何处理这种情况?

mic*_*alk 5

我认为您正在寻找这样的比较器:

Comparator<MyClass> comparator = Comparator.comparing(MyClass::getId, Comparator.nullsLast(Comparator.reverseOrder()))
                .thenComparing(MyClass::getCreateDate);
Run Code Online (Sandbox Code Playgroud)

测试它的代码:

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));
Run Code Online (Sandbox Code Playgroud)

输出为:

4 2019-06-14
4 2019-06-15
2 2019-06-14
null 2019-06-14
null 2019-06-15
Run Code Online (Sandbox Code Playgroud)

如果您想nulls成为第一个,只需更改nullsLastnullsFirst