Java 8 - 对具有空值的整数列表进行排序



假设你有一个包含空值的整数列表

List<Integer> integers = Arrays.asList(null, 9, 11, 7, 5, null);

现在,如果您想获得最大值,可以尝试

OptionalInt max = integers.stream()
.mapToInt(Integer::valueOf)
.max();

如果列表不包含空值,这将起作用。在我们的例子中,将有一个NullPointerException。经过一些研究,我可以看到这样的解决方案

Optional<Integer> max = integers.stream()
.max(Comparator.nullsFirst(Comparator.naturalOrder()));

如果您认为空值小于非空值,则它有效。但是,如果您希望它们更大并将nullsFirst更改为nullsLast

Optional<Integer> max = integers.stream()
.max(Comparator.nullsLast(Comparator.naturalOrder()));

那么你将再次遇到NullPointerException。

我很感兴趣 - 考虑到它的文档声明它是空友好的,为什么 nullsLast 在这种情况下不起作用? 对包含空值的整数列表进行排序的最佳方法是什么?

感谢您的想法!

这与Comparator本身无关:

List<Integer> result = integers.stream()
.sorted(Comparator.nullsLast(Comparator.naturalOrder()))
.collect(Collectors.toList());
System.out.println(result); // [5, 7, 9, 11, null, null]

你把你的空值放在最后,那将是max;在空上调用max抛出该NullPointerException

Stream#max的文档指出:

抛出:空指针异常 - 如果最大元素为空

由于您提供了一个比较器,它将null视为最大元素,因此这就是它引发异常的原因。

这是堆栈跟踪在示例中null尝试返回stateOptional.of(state);时指示的内容,如果传递的值null,则Optional.of抛出 NPE。

Comparator.nullsLast工作正常,例如:

Integer max = 
Collections.max(integers, Comparator.nullsLast(Comparator.naturalOrder()));

确实会给你null.

如果您认为null大于任何非null值,那么当列表包含任何null时,最大值当然会null

由于Stream.max已经记录了当结果null时它将抛出NullPointerException,这是预期的行为。设计原理类似于findFirst(),这在本次问答中已经讨论过。

请注意,即使

Optional<Integer> max = integers.stream()
.max(Comparator.nullsFirst(Comparator.naturalOrder()));

仍然可以失败,即如果所有值都null.但是在这里使用自定义Comparator是没有意义的,因为解决方案很简单:

OptionalInt max = integers.stream()
.filter(Objects::nonNull)
.mapToInt(Integer::valueOf)
.max();

当你得到一个空的OptionalInt时,你仍然可以测试integers.isEmpty()以确定是所有元素都null还是根本没有元素。

相关内容

  • 没有找到相关文章

最新更新