我对Java 8中的 APIStream#findAny()
和一点都不感到困惑。Stream#findFirst()
Stream
我了解到的是,例如当与filter一起使用时,两者都会从流中返回第一个匹配的元素?
那么,为什么要用两种方法完成同一任务?我想念什么吗?
我对Java 8中的 APIStream#findAny()
和一点都不感到困惑。Stream#findFirst()
Stream
我了解到的是,例如当与filter一起使用时,两者都会从流中返回第一个匹配的元素?
那么,为什么要用两种方法完成同一任务?我想念什么吗?
Answers:
我了解到的是,例如当与filter一起使用时,两者都会从流中返回第一个匹配的元素?
这不是真的。根据javadoc Stream#findAny()
:
返回
Optional<T>
描述流中某些元素的描述;Optional<T>
如果流为空,则返回空。该操作的行为明确地是不确定的。可以自由选择流中的任何元素。这是为了在并行操作中获得最佳性能。
whileStream.findFirst()
将严格返回Optional<T>
描述流的第一个元素。该班没有一个方法,所以我想你的意思。Stream
.findOne()
.findFirst()
findAny
都可以(随机)返回该元素中的任何元素,尤其是在并行流操作中
不,两者都不会返回Stream的第一个元素。
来自Stream.findAny()
(强调我的):
返回
Optional
描述流中某些元素的描述;Optional
如果流为空,则返回空。这是短路端子操作。
该操作的行为明确地是不确定的。可以自由选择流中的任何元素。这是为了在并行操作中获得最佳性能。代价是对同一源的多次调用可能不会返回相同的结果。(如果需要稳定的结果,请
findFirst()
改用。)
因此,简单地说,它可能会或可能不会选择Stream的第一个元素。
对于当前特定于Oracle的实现,我相信它将返回非并行管道中的第一个元素。但是,在并行管道中,它并不总是(例如执行System.out.println(IntStream.range(0, 100).parallel().findAny());
,OptionalInt[50]
当我运行它时返回)。无论如何,您一定不能依靠它。
findFirst返回流的第一个元素,但是findAny可以自由选择流中的任何元素。
List<String> lst1 = Arrays.asList("Jhonny", "David", "Jack", "Duke", "Jill","Dany","Julia","Jenish","Divya");
List<String> lst2 = Arrays.asList("Jhonny", "David", "Jack", "Duke", "Jill","Dany","Julia","Jenish","Divya");
Optional<String> findFirst = lst1.parallelStream().filter(s -> s.startsWith("D")).findFirst();
Optional<String> fidnAny = lst2.parallelStream().filter(s -> s.startsWith("J")).findAny();
System.out.println(findFirst.get()); //Always print David
System.out.println(fidnAny.get()); //Print Jack/Jill/Julia :behavior of this operation is explicitly nondeterministic
我只想说,当谨慎findFirst()
而findAny()
同时使用。
从它们的Javadoc(此处和此处)开始,这两个方法都从流中返回一个任意元素-除非流具有遇到顺序,在这种情况下,findFirst()
将返回第一个元素,而findAny()
将返回任何元素。
假设我们有自定义的list
ISBN和BOOK名称。对于场景,请看以下示例:
public class Solution {
private Integer ISBN;
private String BookName;
public Solution(int i, String string) {
ISBN =i;
BookName = string;
}
//getters and setters
}
public static void main(String[] args) {
List<Solution> Library = Arrays.asList(new Solution(12,"Java in Action"),new Solution(13,"Java 8"),new Solution(15,"Java 8 Features"),new Solution(16,"Java in Action"));
System.out.println(Library.stream()
.map(p->p.getBookName())
.sorted(Comparator.reverseOrder())
.findFirst());
}
输出:Optional[Java in Action]
在某些情况下,书名相同但ISBN号不同,在这种情况下,书的分类和查找可能非常相似,findAny()
并且会得出错误的结果。考虑这样一种情况,其中5本书被命名为“ Java参考”,但是具有不同的ISBN号,并且findFirst()
按名称列出的书将与findAny()
。
考虑以下情况:
ISBN Name Of book
+-----+------------------+
| 100 | Java-8 in Action |
+-----+------------------+
| 101 | Java-8 in Action |
+-----+------------------+
| 102 | Java-8 in Action |
+-----+------------------+
| 103 | Java-8 in Action |
+-----+------------------+
| 104 | Java-8 in Action |
+-----+------------------+
即使按BookByName排序,这里的findFirst()和findAny()也会给出相同的结果。
filter
应用a之后,findAny
也可以返回任何元素,包括与应用的过滤器不匹配的元素吗?