Java 使用默认实现的空安全映射比较器

Java 使用默认实现的空安全映射比较器,java,java-8,comparator,Java,Java 8,Comparator,是否有一种内置的可能性,可以在Java 8中创建空安全映射比较器,而无需编写自己的比较器实现 运行以下代码时,它会导致NPE,因为Comparator.comparating()的keyExtractor参数可能返回null值: public class ToSort { private String sortBy; public ToSort(String sortBy) { this.sortBy = sortBy; } publ

是否有一种内置的可能性,可以在Java 8中创建空安全映射比较器,而无需编写自己的
比较器
实现

运行以下代码时,它会导致NPE,因为
Comparator.comparating()
keyExtractor
参数可能返回
null
值:

public class ToSort
{

    private String sortBy;

    public ToSort(String sortBy)
    {
        this.sortBy = sortBy;
    }

    public String getSortBy()
    {
        return sortBy;
    }

    public static void main(String[] args)
    {
        // mapping comparator
        Comparator<ToSort> comp = Comparator.comparing(ToSort::getSortBy);                          
        SortedSet<ToSort> set = new TreeSet<>(comp);
        ToSort o1 = new ToSort("1");
        ToSort o2 = new ToSort(null);

        set.add(o1);

        System.out.println(set.contains(o2)); //NPE because o2.getSortBy() == null

    }
}

找到了一个可能的解决方案:

Comparator.comparing(ToSort::getSortBy, 
      Comparator.nullsFirst(Comparator.naturalOrder())
)

所以这个解决方案之所以有效,是因为比较器的嵌套顺序。在您的问题中,最里面的比较器(因此也是第一个被执行的比较器)是
ToSort::getSortBy
,而
nullsFirst
被包裹在它周围。在这个回答中,首先执行
nullsFirst
比较器,在null返回
getSortBy
调用之前提供安全性
Comparator.comparingNullsFirst(ToSort::getSortBy)
Comparator.comparing(ToSort::getSortBy, 
      Comparator.nullsFirst(Comparator.naturalOrder())
)