最有可能是重复,但我无法找到任何特定的。
public static void main(String[] args) {
System.out.println(
Arrays.asList(null, null, 1)
.stream()
.filter(obj -> obj == null)
.findAny()
.isPresent()
);
}
至少应该工作(即返回 false ,因为 findAny 返回可选)。
NullPointerException
被抛出
是错误还是功能?
感谢您的意见和解释。
答案 0 :(得分:10)
此行为在findAny()的Javadoc中突出显示 https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#findAny--
返回:描述此流的某个元素的可选项,或者 empty如果流为空,则为可选
抛出:NullPointerException - 如果选择的元素为null
由于您正在进行过滤,因此Stream只包含空值,因此您将获得预期的NullPointerException。
答案 1 :(得分:8)
如果您将代码更改为使用anyMatch
而不是filter(...).findAny().isPresent()
,则可以按预期运行:
boolean found = Arrays.asList(null, null, 1)
.stream()
.anyMatch(Objects::isNull);
System.out.println(found); // true
至于您的版本因NPE而失败的原因,在Stream.findAny
docs中说:
抛出:
NullPointerException - if the element selected is null
所以这是预期的行为。
修改强>
发生NPE是因为Optional.of
用于构造findAny()
返回的值。 Optional.of
需要一个非空值,根据文档:
返回一个带有指定的当前非空值的Optional。
无论如何,在构建Optional.of
返回的值时,我想您想知道为什么Optional.ofNullable
被用来代替findAny()
...
好吧,我只能推测,但我认为findAny()
和findFirst()
旨在找到符合某些条件的值,即Person
,其名称以{{1}开头}。您可能希望知道您的信息流中是否有A
个元素。但在这种情况下,你不需要真正找到这样的元素,因为你已经知道,如果你找到它,它就会......嗯......只是null
。因此,如果您的信息流包含null
,那么检查就足够了,您可以完全使用null
查找是否属于这种情况。
换句话说,找到一个anyMatch()
的元素并不是很有用,因为你无法对它做任何事情(除了知道它之外) null
)。
编辑2:正如用户@ holi-java在下面的评论中指出,如果null
返回findAny()
,则无法知道{{1}找到与否。在这种情况下,结果将是不明确的,因为Optional.ofNullable(null)
,即它会导致混淆,因为null
,意味着找不到匹配的值。
答案 2 :(得分:2)
这不是一个错误,它是在get()
的实例上调用Optional
而导致NPE的结果。导致它的确切调用是findAny()
,它给出了以下堆栈跟踪:
Exception in thread "main" java.lang.NullPointerException
at java.util.Objects.requireNonNull(Objects.java:203)
at java.util.Optional.<init>(Optional.java:96)
at java.util.Optional.of(Optional.java:108)
at java.util.stream.FindOps$FindSink$OfRef.get(FindOps.java:193)
at java.util.stream.FindOps$FindSink$OfRef.get(FindOps.java:190)
at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.findAny(ReferencePipeline.java:469)
at StreamTest.main(StreamTest.java:17)
同样the documentation for findAny()
指定可以抛出NPE:
抛出:NullPointerException - 如果选择的元素为null
您可以使用anyMatch()
:
Arrays.asList(null, null, 1).stream().anyMatch(obj -> obj == null)
ofNullable()
?findAny()
API的设计者不想假设null
是否表示该值不存在(缺少值)或存在但是等于null。此外,您仍然可以在任何信息流上使用map(Optional::isNullable)
。
答案 3 :(得分:2)
Here's findAny()
的文档,这就是它所说的:
引发:NullPointerException -
如果所选元素为空
因此,如果您尝试在空对象上调用findAny()
,则始终会获得NPE。
您可以使用anyMatch
代替,例如:
Arrays.asList(null, null, 1).stream().anyMatch(e -> e == null));