首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Comparator.nullsLast时的NullPointerException

使用Comparator.nullsLast时的NullPointerException
EN

Stack Overflow用户
提问于 2019-01-29 04:48:08
回答 1查看 2.8K关注 0票数 3

我有下面两个类MyRange和MyCustomValue的代码-

代码语言:javascript
复制
class MyRange {
    private Long id;
    private Double minValue;
    private Double maxValue;

    // getters and setters
    // equals, hashCode and toString

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null || getClass() != obj.getClass())
            return false;
        MyRange other = (MyRange) obj;
        return Objects.equals(this.id, other.id) && 
               Objects.equals(this.minValue, other.minValue) &&
               Objects.equals(this.maxValue, other.maxValue);
    }
}

class MyCustomValue {
    private String value;
    private MyRange myrange;

    //getters and setters
    // equals, hashCode and toString

}

如果MyCustomValue中的value为null,我想把它放在最后。所以我像下面这样写比较器

代码语言:javascript
复制
public static final Comparator<MyCustomValue> externalMVComparator = (emv1, emv2) -> {
    if(emv1.getValue() != null && emv2.getValue() == null) {
        return -1;
    } else if (emv1.getValue() == null && emv2.getValue() != null) {
        return 1;
    } else {
        return myrangeMinValueComparator.compare(emv1, emv2);
    }
}

private static final Comparator<MyRange> minValueComparator =  Comparator.nullsLast(Comparator.comparingDouble(value -> value.getMinValue()));
private static final Comparator<MyCustomValue> myrangeMinValueComparator = Comparator.nullsLast(Comparator.comparing(MyCustomValue::getMyrange, minValueComparator));

上面的比较器工作正常。所以我决定像下面这样修改externalMVComparator (也就是说,使用thenComparing来提高可读性)

代码语言:javascript
复制
private static final Comparator<MyCustomValue> valueComparator = Comparator.nullsLast(Comparator.comparing(MyCustomValue::getValue));
public static final Comparator<MyCustomValue> externalMVComparator2 = Comparator.nullsLast(valueComparator.thenComparing(myrangeMinValueComparator));

但是在NullPointerException中使用externalMVComparator2对列表进行排序。我在代码中做错了什么?

用于测试的代码-

代码语言:javascript
复制
MyCustomValue emv1 = new MyCustomValue("v1", new MyRange(1L, 0.71, 0.79));
MyCustomValue emv2 = new MyCustomValue(null, new MyRange(2L, 0.53, 0.65));
MyCustomValue emv3 = new MyCustomValue("v2", new MyRange(3L, 0.28, 0.42));
MyCustomValue emv4 = new MyCustomValue(null, new MyRange(4L, 0.06, 0.27));
List<MyCustomValue> shuffledList1 = Arrays.asList(emv1, emv2, emv3, emv4);
Collections.shuffle(shuffledList1);
shuffledList1.sort(MyCustomValue.externalMVComparator2);
Assert.assertEquals(shuffledList1, Arrays.asList(emv3, emv1, emv4, emv2));

堆栈跟踪错误-

代码语言:javascript
复制
    Exception in thread "main" java.lang.NullPointerException
    at java.util.Comparator.lambda$comparing$77a9974f$1(Comparator.java:469)
    at java.util.Comparator.lambda$thenComparing$36697e65$1(Comparator.java:216)
    at java.util.Comparators$NullComparator.compare(Comparators.java:83)
    at java.util.Comparators$NullComparator.compare(Comparators.java:83)
    at java.util.TimSort.countRunAndMakeAscending(TimSort.java:355)
    at java.util.TimSort.sort(TimSort.java:220)
    at java.util.Arrays.sort(Arrays.java:1438)
    at java.util.Arrays$ArrayList.sort(Arrays.java:3895)
    at TestNullComparator.main(TestNullComparator.java:15)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-29 06:41:08

问题出在下面这一行(为了清楚起见,我删除了Comparator. ):

代码语言:javascript
复制
Comparator<MyCustomValue> valueComparator = nullsLast(comparing(MyCustomValue::getValue));

您创建的Comparator将处理MyCustomValue类型的null值。它不会处理getValue返回的null%s。您必须使用双参数版本的Comparator.comparing,并为值提供一个null-safe比较器:

代码语言:javascript
复制
valueComparator = comparing(MyCustomValue::getValue, nullsLast(naturalOrder()));

上面的代码将处理您实际想要按value排序的常见情况。当我查看您的代码时,我认为您的意思是只使用value进行null检查,否则就不想按它排序。如果是这样的话,您可以使用nullsLast( (x,y) -> 0)作为comparing的空安全第二个参数,该参数将把所有字符串视为相等。您也可以使用valueComparator = comparing(mcv -> mcv.getValue() == null),因为true以自然的顺序使用false,但这可能不太清楚。

如果您还想处理MyCustomValuenull,则必须再次将其包装在nullsLast中。

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

https://stackoverflow.com/questions/54410063

复制
相关文章

相似问题

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