java8流短路
读了一点Java8,我在博客上解释了一些关于流和流的缩减,以及何时可以缩短缩减。在底部,它指出: 注意在java8流短路,java,java-8,java-stream,short-circuiting,Java,Java 8,Java Stream,Short Circuiting,读了一点Java8,我在博客上解释了一些关于流和流的缩减,以及何时可以缩短缩减。在底部,它指出: 注意在findFirst或findAny的情况下,我们只需要与谓词匹配的第一个值(尽管findAny不保证返回第一个值)。但是,如果流没有排序,那么我们希望findFirst的行为类似于findAny。操作allMatch、noneMatch和anyMatch可能根本不会使流短路,因为可能需要评估所有值才能确定运算符是true还是false。因此,使用这些函数的无限流可能不会终止 我知道findFi
findFirst
或findAny
的情况下,我们只需要与谓词匹配的第一个值(尽管findAny
不保证返回第一个值)。但是,如果流没有排序,那么我们希望findFirst
的行为类似于findAny
。操作allMatch
、noneMatch
和anyMatch
可能根本不会使流短路,因为可能需要评估所有值才能确定运算符是true
还是false
。因此,使用这些函数的无限流可能不会终止
我知道findFirst
或findAny
可能会使还原短路,因为一旦找到元素,就不需要进一步处理
但是为什么allMatch
、noneMatch
和anyMatch
都不可能做到这一点呢?对于allMatch
,如果发现一个与谓词不匹配,则可以停止处理。没有一样。而anyMatch
对我来说尤其没有意义,因为它几乎等同于findAny
(返回的内容除外)
对于findFirst/Any
,也可以说这三个可能不会短路,因为可能需要评估所有值
我有没有遗漏一些根本性的区别?我真的不明白发生了什么吗?当javadoc说“可能不会短路”时,它只是指出这不是一个短路操作,根据值,整个流可能会被处理
另一方面,
findFirst
和findAny
保证短路,因为一旦满足它们,它们就不需要处理流的其余部分。anyMatch、noneMatch和allMatch返回布尔值,因此它们可能必须检查all来证明逻辑
findFirst和findAny只关心找到他们能找到的第一个并返回
编辑:
对于给定的数据集,Match方法保证始终返回相同的值,但是Find方法不会返回相同的值,因为顺序可能会变化,并影响返回的值
所描述的短路是指给定数据集的查找方法缺乏一致性。答案已更新 我会说博客文章说“findFirst或findAny我们只需要匹配谓词的第一个值”是错误的 在、和的javadoc中: 这是一种短路终端操作
但是,请注意,
findFirst
和findAny
没有谓词。因此,它们都可以在看到第一个/任何值时立即返回。其他3个是有条件的,如果条件从未触发,则可能永远循环。根据Oracle的流文档:
如果终端操作在无限输入时可能在有限时间内终止,则终端操作为短路。在管道中进行短路操作是无限流处理在有限时间内正常终止的必要条件,但不是充分条件
所有五个功能都有一行:
这是一种短路终端操作
在函数的描述中。有一个细微的区别,因为anyMatch
family使用谓词,而findAny
family不使用谓词。从技术上讲,findAny()
看起来像anyMatch(x->true)
和anyMatch(pred)
看起来像filter(pred).findAny()
。所以这里我们有另一个问题。考虑到我们有一个简单的无限流:
Stream<Integer> s = Stream.generate(() -> 1);
Stream<Integer> s = Stream.generate(() -> 1).filter(x -> x < 0);
结果流也是无限的吗?这是个棘手的问题。它实际上不包含任何元素,但要确定这一点(例如,使用.iterator().hasNext()
),我们必须检查无限多的底层流元素,因此此操作永远不会完成。我也会称这种流为无限流。但是,使用这样的流时,anyMatch
和findAny
都不会完成:
Stream.generate(() -> 1).filter(x -> x < 0).anyMatch(x -> true);
Stream.generate(() -> 1).filter(x -> x < 0).findAny();
Stream.generate(()->1).filter(x->x<0).anyMatch(x->true);
Stream.generate(()->1).filter(x->x<0.findAny();
因此findAny()
也不能保证完成,它取决于之前的中间流操作
总而言之,我认为那篇博文很容易误导读者。在我看来,无限流行为最好用官方语言来解释。在“可能不”中用“可能不”,在“不允许”中用“可能不”。@Andreas是的,我只是不明白区别来自何处。按照我的观点,所有的都可以短路?但是任何匹配都可以短路?如果最后一个值是匹配的,那么是的。重点是Match方法总是在同一数据集上返回相同的值,但Find方法不能保证一致性,因为顺序可能不同。这种不一致性是描述的短路,但谓词也可能发生这种情况,只要它们('t)满足要求。博客:“allMatch、noneMatch和anyMatch操作可能根本不会使流短路,因为可能需要计算所有值才能确定运算符是真还是假。“这显然是不正确的,因为只要找到第一个不匹配项,allMatch
就可以确定为false。@正如我所说的,令人遗憾的是,博客文章是错误的。它们都可能短路该博客认为其中3个可能永远运行,这是对的,但它说这一切都错了。没有回答关于allMatch
的问题。