首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java8零安全比较

Java8零安全比较
EN

Stack Overflow用户
提问于 2018-05-07 13:24:03
回答 2查看 4.8K关注 0票数 8

在比较两种产品时有问题。我希望比较它们中每一个的vintage (这是可选的)属性。但是,每当该属性为null时,就会抛出NPE。我想用Comparator.nullsLast(..)我可以处理空值..。但似乎我对这是如何工作的有误解,或者代码有问题。我需要更改什么才能使工作成为零友好型?

代码语言:javascript
复制
@Override
public int compare(IProduct product1, IProduct product2) throws ProductComparisonException {

    Comparator<IShopProduct> comparator =
        Comparator.nullsLast(Comparator.comparing(IShopProduct::getVintage));

    return comparator.compare((IShopProduct)product1.getProvidedProductData(),
                              (IShopProduct)product2.getProvidedProductData());
}

提前感谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-07 13:32:28

它应该是

代码语言:javascript
复制
Comparator<IShopProduct> comparator = 
            Comparator.comparing( IShopProduct::getVintage, 
                             Comparator.nullLast(naturalOrder()));

Comparator.nullFirst()/nullLast()认为空值大于/小于nonNull对象

编辑

这是Comparator.comparing()的实现:

代码语言:javascript
复制
public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
        Function<? super T, ? extends U> keyExtractor)
{
    Objects.requireNonNull(keyExtractor);
    return (Comparator<T> & Serializable)
        (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}

如您所见,它调用了keyExtractor.apply(c1).compareTo(),因此如果keyExtractor.apply(c1)null,它将抛出NPE。

我建议的代码使用以下函数:

代码语言:javascript
复制
public static <T, U> Comparator<T> comparing(
        Function<? super T, ? extends U> keyExtractor,
        Comparator<? super U> keyComparator)
{
    Objects.requireNonNull(keyExtractor);
    Objects.requireNonNull(keyComparator);
    return (Comparator<T> & Serializable)
        (c1, c2) -> keyComparator.compare(keyExtractor.apply(c1),
                                          keyExtractor.apply(c2));
}

基本上,它将提取值,然后将比较值传递给Comparator

这些值将传递给naturalOrder()比较器,后者解析为value1.compareTo(value2)。通常情况下,它会抛出NPE,但是我们已经用Comparator.nullLast包装了它,后者有特殊的null处理程序。

票数 7
EN

Stack Overflow用户

发布于 2018-05-07 13:56:53

如果传入的密钥提取器函数是比较,或者提取的属性是null,则该方法的重载将引发异常。既然您提到了vintage属性有时可以是null,那么这就是NullPointerException的原因。

要克服这一问题,另一种办法是使用这个比较器:

代码语言:javascript
复制
 Comparator<IShopProduct> comparator = 
      Comparator.comparing(IShopProduct::getVintage,
                Comparator.nullsLast(naturalOrder()));

密钥提取器,即IShopProduct::getVintage是用于提取排序密钥的函数。

密钥比较器,即Comparator.nullsLast(Comparator.naturalOrder()),用于比较排序键。

这里的Comparator.naturalOrder()只返回一个比较器,该比较器按自然顺序比较Comparable对象。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50215341

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档