gpt4 book ai didi

java - 使用 Comparator.nullsLast 时出现 NullPointerException

转载 作者:行者123 更新时间:2023-11-30 06:41:54 30 4
gpt4 key购买 nike

我有以下代码,其中包含 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

}

如果 MyCustomValue 中的 value 为空,我希望它在最后。所以我像下面这样写比较器

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。我的代码有什么问题吗?

用于测试的代码-

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));

错误堆栈跟踪 -

    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)

最佳答案

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

Comparator<MyCustomValue> valueComparator = nullsLast(comparing(MyCustomValue::getValue));

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

valueComparator = comparing(MyCustomValue::getValue, nullsLast(naturalOrder()));

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

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

关于java - 使用 Comparator.nullsLast 时出现 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54410063/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com