Lambda 比较器:如何使用nullsFirst和StreamAPI?

Lambda 比较器:如何使用nullsFirst和StreamAPI?,lambda,java-8,comparator,nullable,Lambda,Java 8,Comparator,Nullable,我正在努力编写一个处理空字段的比较器 我有这样的pojo: import static java.util.Comparator.comparingInt; import java.math.BigDecimal; import java.util.Comparator; import lombok.Builder; import lombok.Data; import org.jetbrains.annotations.NotNull; @Data @Builder public clas

我正在努力编写一个处理空字段的
比较器

我有这样的pojo:

import static java.util.Comparator.comparingInt;

import java.math.BigDecimal;
import java.util.Comparator;
import lombok.Builder;
import lombok.Data;
import org.jetbrains.annotations.NotNull;

@Data
@Builder
public class Pojo implements Comparable<Pojo> {
  private Integer id;
  private BigDecimal cost;

  private static final Comparator<Pojo> COMPARATOR =
      comparingInt((Pojo p) -> p.id).thenComparing(p -> p.cost);

  @Override
  public int compareTo(@NotNull Pojo pojo) {
    return COMPARATOR.compare(this, pojo);
  }
}

但这没有帮助。

以下是以下文件:

返回字典顺序比较器,该比较器具有一个函数,该函数提取要与给定的
比较器进行比较的键

实施要求:

此默认实现的行为方式类似于
然后比较(比较(keyExtractor,cmp))

其中提到:

接受一个函数,该函数从类型
T
中提取排序键,并返回一个
比较器
,该比较器使用指定的
比较器对排序键进行比较

如果指定的函数和比较器都可序列化,则返回的比较器可序列化

如文档所述,是
Comparator
参数用于比较
函数
提取的值。这意味着
比较器必须能够处理
null
。这与你看起来想要做的相反

使
null
-安全
比较器
,而不必手动编写代码的一种方法是使用或。这两种方法都包装了另一个
比较器
,如果要比较的两个元素都是非
null
,则将调用该比较器。基本上,由
nullsFirst
nullsLast
返回的
Comparator
是一个拦截器

现在所需要的就是
比较器
,它将被
null
-safe
比较器
包装。由于
整数
大十进制
都是
可比的
,因此我们可以使用

假设
id
cost
都可以
null
,并且您希望
null
值在每种情况下都排在第一位,那么以下内容应该适用于您:

comparing(p -> p.id, nullsFirst(naturalOrder()))
        .thenComparing(p -> p.cost, nullsFirst(naturalOrder()));
或者,如果您假设
id
永远不会为
null
,您可以这样修改上述内容:

comparing(p -> p.id)
        .thenComparing(p -> p.cost, nullsFirst(naturalOrder()));

在比较之前是否可以过滤掉空对象?
comparing(p -> p.id, nullsFirst(naturalOrder()))
        .thenComparing(p -> p.cost, nullsFirst(naturalOrder()));
comparing(p -> p.id)
        .thenComparing(p -> p.cost, nullsFirst(naturalOrder()));