使用 Comparator.nullsLast 时出现 NullPointerException

我有以下代码,其中包含 2 个类 MyRange 和 MyCustomValue -


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


}

如果它value是空的,MyCustomValue我希望它在最后。所以我写了如下的比较器


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更多的可读性)


private static final Comparator<MyCustomValue> valueComparator = Comparator.nullsLast(Comparator.comparing(MyCustomValue::getValue));

public static final Comparator<MyCustomValue> externalMVComparator2 = Comparator.nullsLast(valueComparator.thenComparing(myrangeMinValueComparator));

但是对列表进行排序,externalMVComparator2结果为NullPointerException. 我的代码中有什么错误?

达令说
浏览 527回答 1
1回答

白衣非少年

问题出在以下行(Comparator.为清楚起见,我删除了):Comparator<MyCustomValue>&nbsp;valueComparator&nbsp;=&nbsp;nullsLast(comparing(MyCustomValue::getValue));Comparator您所做的将处理类型的null值MyCustomValue。它不会处理由 .null返回的 s&nbsp;getValue。您必须使用 2 参数版本Comparator.comparing并null为值提供 -safe 比较器:valueComparator&nbsp;=&nbsp;comparing(MyCustomValue::getValue,&nbsp;nullsLast(naturalOrder()));以上将处理您实际想要排序的常见情况value。当我查看您的代码时,我认为您的意思是只使用valuefornull检查,否则不想按它排序。如果是这种情况,您可以将nullsLast( (x,y) -> 0)&nbsp;其用作 null 安全的第二个参数,因为comparing它会将所有字符串视为相等。您也可以使用valueComparator = comparing(mcv -> mcv.getValue() == null)因为true按false自然顺序排列,但这可能不太清楚。如果您还想处理nulls of&nbsp;MyCustomValue,则必须再次将其包装nullsLast起来。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java