gpt4 book ai didi

java - 为什么当结果为空时 Stream.reduce(BinaryOperator) 会抛出 NullPointer?

转载 作者:行者123 更新时间:2023-11-30 10:32:40 26 4
gpt4 key购买 nike

我有一个要减少的枚举值流。如果流为空或包含不同的值,我需要 null。如果它只包含(多个实例)单个值,我想要那个值。

[]              null
[A, B, A] null
[A] A
[A, A, A] A

我试着用 reduce 来做:

return <lots of filtering, mapping, and other stream stuff>
.reduce((enum1, enum2) -> enum1 == enum2 ? enum1 : null)
.orElse(null);

不幸的是,这不起作用,因为当结果为 null 时,此 reduce 方法会抛出一个 NullPointerException。有谁知道为什么会这样?为什么 null 不是有效结果?

目前,我是这样解决的:

MyEnum[] array = <lots of filtering, mapping, and other stream stuff>
.distinct()
.toArray(MyEnum[]::new);
return array.length == 1 ? array[0] : null;

虽然这行得通,但我对这种“迂回”并不满意。我喜欢 reduce,因为它似乎很合适,而且可以将所有内容放入一个流中。

谁能想到 reduce 的替代方案(理想情况下代码不要太多)?

最佳答案

通常,所有返回 Optional 的 Stream 方法都不允许 null 值,因为不可能告诉 null 结果和“没有结果”(空流)分开。

您可以使用占位符值来解决这个问题,不幸的是,这需要暂停类型安全(因为在枚举集之外没有类型兼容的值):

return <lots of filtering, mapping, and other stream stuff>
.reduce((enum1, enum2) -> enum1 == enum2? enum1: "")
.map(r -> r==""? null: (MyEnum)r)
.orElse(null);
如果映射函数返回 null

Optional.map 将返回一个空的可选值,因此在该步骤之后,一个空流和一个 null结果无法再区分,orElse(null) 将在这两种情况下返回 null

但也许绕行数组只会让人感觉不尽如人意,因为数组不是中间结果的最佳选择?怎么样

EnumSet<MyEnum> set = <lots of filtering, mapping, and other stream stuff>
.collect(Collectors.toCollection(() -> EnumSet.noneOf(MyEnum.class)));
return set.size()==1? set.iterator().next(): null;

EnumSet 只是一个位集,如果 enum 类型不超过 64 个常量,则为单个 long 值。这比数组便宜得多,而且由于 Set 自然不同,因此不需要对流进行 distinct() 操作,这将创建一个 HashSet 引擎盖下。

关于java - 为什么当结果为空时 Stream.reduce(BinaryOperator) 会抛出 NullPointer?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42581621/

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