- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我不知道 Streams 内部是如何工作的,但我一直想知道为什么 Stream#findAny()
存在,而有 Stream#findFirst()
。 Find first 建议流保持创建它们的数组/Collection
/Iterator
的顺序。那么为什么要使用任何?如果与您获得的元素无关,它也可能是第一个。从我的想法来看,findFirst
应该总是在恒定时间内执行。
Stream#findAny()
的 Javadoc 声明:
The behavior of this operation is explicitly nondeterministic; it isfree to select any element in the stream. This is to allow formaximal performance in parallel operations; the cost is that multipleinvocations on the same source may not return the same result. (If astable result is desired, use {@link #findFirst()} instead.)
但即便如此,元素的顺序还不知道吗?提供的数据结构保持不变。
最佳答案
Stream#findAny当我们在不注意遇到顺序的情况下寻找元素时使用它。
来自 Lino 的评论在正确总结差异的答案时:
Take a stream of two elements and process them to get a result. Thefirst takes 400 years to complete. The second 1 minute.
findFirst
willwait the whole 400 years to return the first elements result. WhilefindAny
will return the second result after 1 minute. See thedifference? Depending on the circumstances of what exactly you'redoing, you just want the fastest result, and don't care about theorder.
考虑一下 findFirst
的这段代码:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> result = list
.stream()
.filter(num -> num < 4)
.findFirst(); // .findAny();
这里,findAny
操作为findFirst
,仍然不能保证。 在我的机器上,经过 10 次奇数运行后,输出始终为 1
。
现在,让我们考虑一个并行流,findAny
是为它设计的:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> result = list
.stream()
.parallel()
.filter(num -> num < 4)
.findAny();
现在是我机器上的输出 3
。但它可以是任何 1
、2
或 3
。
让我们对有利于 findAny
的输入进行一些基准测试(即,谓词在流中间之后应该为真)。
List<Integer> list = IntStream.rangeClosed(1, 1000000).boxed().collect(Collectors.toList());
long findFirstStartTime = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
list.stream().filter(num -> num > 500000).findFirst();
}
long findFirstEndTime = System.currentTimeMillis();
long findAnyStartTime = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
list.stream().parallel().filter(num -> num > 500000).findAny();
}
long findAnyEndTime = System.currentTimeMillis();
System.out.println("findFirst time taken: " + (findFirstEndTime - findFirstStartTime));
System.out.println("findAny time taken: " + (findAnyEndTime - findAnyStartTime));
findFirst
将按顺序进行,直到流的中间,而 findAny
将按全能者的意愿进行。结果令人震惊:
findFirst time taken: 29324
findAny time taken: 623
使用 JMH Benchmarking带参数:
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@Measurement(iterations = 10)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
Benchmark Mode Cnt Score Error Units
FindAny.findAny avgt 50 191700.823 ± 251565.289 ns/op
FindAny.findFirst avgt 50 4157585.786 ± 355005.501 ns/op
关于java - 为什么 Stream#findAny() 存在?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73235495/
Stream 的 findAny 方法选择此流中的任何元素。 findAny 方法的行为是不确定的,可以自由选择此流中的任何元素。 findAny 方法对于在并行操作中获得最大性能很有用,但不能保证每
考虑这段代码 Object found = collection.stream() .filter( s -> myPredicate1(s)) .filter( s -> myPre
我正在使用流过滤器 findAny.orElse,但它没有像我预期的那样工作,所以我想我不了解它的真正工作原理。这是我的代码 return Stream.of(getObjectAttributeVa
我不知道 Streams 内部是如何工作的,但我一直想知道为什么 Stream#findAny() 存在,而有 Stream#findFirst()。 Find first 建议流保持创建它们的数组/
我正在尝试查找列表中与给定谓词匹配的第一个(任何)成员,如下所示: Item item = items.parallelStream() .map(i -> i.doSomethingExpens
我想知道如何在数据流中使用 findAny(),当它没有找到任何巧合时,它不会返回 null。 String CountryFinal= "Spain"; List listContries = ne
在我的 Spring 应用程序中,我有一个文档类型为 QuoteOfTheDay 的 Couchbase 存储库。 .该文档非常基础,只有一个 UUID 类型的 id 字段、String 类型的 va
我想过滤列表以查找具有非空属性的元素并返回该属性: list.stream.map(a -> StringUtils.trimToEmpty(a.getProp())).filter( p -> St
我需要从嵌套的List中找到一些对象。 我认为不需要类代码,因为过滤是在嵌套的 For-Each 循环 中公开的。 int value = someValue; MyObject found = nu
我想找到给定哈希值的消息。为此,我想遍历 ascii 小写字母和数字的所有可能的 n 长度排列的集合,并检查排列的哈希值是否等于给定的哈希值。 问题:预先计算集合是不可行的,因为空间复杂度是 O(36
我有一个 Array 并想对其元素执行一些匹配。 我开始知道它可以在 java 8 中以两种方式完成: String[] alphabet = new String[]{"A", "B", "C"};
我对 Java 8 中 Stream API 的 Stream#findAny() 和 Stream#findFirst() 有点困惑。 我的理解是两者都会从流中返回第一个匹配的元素,例如,当与过滤器
我是 Java 的 Stream API 的新手,我对这个案例的结果感到困惑: Stream stream = Stream.of("A","B","C","D"); System.out.print
我是一名优秀的程序员,十分优秀!