首页 > 解决方案 > 如何处理 Java 8 比较器中的空值和重复值?

问题描述

我有一个Photo对象:

public class Photo {
    @Id
    private String id;
    private LocalDateTime created;
    private Integer poNumber;
}

poNumber 对于某些照片或一组照片可以为空。我想根据 poNumber 对一组照片进行排序,使最低 poNumber 出现在排序后的集合中。poNumber 也可能在集合中重复。如果 poNumber 重复,则根据创建的排序(最早创建的照片首先出现)。如果 poNumber 为空,则根据创建的排序。

我尝试了以下代码:

Set<Photo> orderedPhotos = new TreeSet<>(
    Comparator.nullsFirst(Comparator.comparing(Photo::getPoNumber))
              .thenComparing(Photo::getCreated));

for (Photo photo : unOrderedPhotos) {
    orderedPhotos.add(photo);
}

NullPointerException只要 poNumber 为空,它就会抛出一个。如果 poNumber 不为空,那么它工作正常。我该如何解决这个问题?

标签: javajava-8comparator

解决方案


我们需要一个解决方案,将其Function<>转换为比较器,但以某种方式将所述null检查添加到链中。

这就是Oleksandr 的回答进入场景的地方:它创建了一个将比较Comparator映射Photo到比较Integers 的 a,然后添加一个 Comparator,它自然地先将这些Integers 与nulls 排序:

Comparator.comparing(Photo::getPoNumber, Comparator.nullsFirst(Comparator.naturalOrder()))

然后这个比较器与另一个考虑创建日期的比较器链接(对于相等的情况)。


推荐阅读