如何在Java8比较器中处理空值和重复值?

如何在Java8比较器中处理空值和重复值?,java,java-8,comparator,Java,Java 8,Comparator,我有一张照片对象: public class Photo { @Id private String id; private LocalDateTime created; private Integer poNumber; } poNumber对于一组中的某些照片或所有照片可以为空。我想根据poNumber对一组照片进行排序,这样最低的poNumber将首先出现在排序的照片集中。poNumber也可以在集合中重复。如果poNumber重复,则根据创建的进行排序(首

我有一张
照片
对象:

public class Photo {
    @Id
    private String id;
    private LocalDateTime created;
    private Integer poNumber;
}
poNumber对于一组中的某些照片或所有照片可以为空。我想根据poNumber对一组照片进行排序,这样最低的poNumber将首先出现在排序的照片集中。poNumber也可以在集合中重复。如果poNumber重复,则根据创建的进行排序(首先显示最早创建的照片)。如果poNumber为null,则根据创建的进行排序

我尝试了以下代码:

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

for (Photo photo : unOrderedPhotos) {
    orderedPhotos.add(photo);
}
设置orderedPhotos=新树集(
Comparator.nullsFirst(Comparator.comparing(Photo::getPoNumber))
.然后比较(照片::getCreated));
用于(照片:无序照片){
orderedPhotos.add(照片);
}

但只要poNumber为null,它就会抛出一个
NullPointerException
。如果poNumber不为null,则它可以正常工作。如何解决此问题?

这将在开始时放置空值

Integer getPoNumber() { return poNumber == null ? Integer.MIN_VALUE : poNumber };

这将在末尾放置空值

Integer getPoNumber() { return poNumber == null ? Integer.MAX_VALUE: poNumber };

否则,实现您自己的比较器来处理空值

我们需要一个解决方案,将
函数
转换为比较器,但要将所述
检查添加到链中

这就是进入场景的地方:它创建了一个
比较器
,它将被比较的
照片
映射到
整数
s的比较,然后添加一个比较器,该比较器自然地将这些
整数
s与
null
s排序:

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

然后,这个比较器与另一个考虑创建日期的比较器链接起来(在相等的情况下)。

按照您编写它的方式,Photo键可以是
null
,但不能是别的

Comparator.nullsFirst( // Photo could be null.
    Comparator.comparing(Comparator.nullsFirst(Photo::getPoNumber)) // poNumber could be null.
              .thenComparing(Comparator.nullsFirst(Photo::getCreated))) // created could be null

如果其中任何一个不能为
null
,则可以删除
比较器。nullsFirst
可以使用双参数重载,例如:

import static java.util.Comparator.*; // for the sake of brevity

Set<Photo> orderedPhotos = new TreeSet<>(
    Comparator.comparing(Photo::getPoNumber, nullsFirst(naturalOrder()))
              .thenComparing(Photo::getCreated));
导入静态java.util.Comparator.*;//为了简洁起见
设置orderedPhotos=新建树集(
Comparator.comparing(Photo::getPoNumber,nullsFirst(naturalOrder()))
.然后比较(照片::getCreated));

“但是每当poNumber为null时,它就会抛出NullPointerException。如果poNumber不为null,那么就可以正常工作。”没有提到创建的
可以为null。我不喜欢
整数
,所以在这种情况下会返回
int
。)他用的就是这个,但是是的@ace,Integer.intValue();带有
poNumber=null的元素应该放在哪里?在该字段中具有非空值的元素之后或之前?