java - Java Stream 生成的值多于限制集
问题描述
由于某种原因,Java Stream 会生成更多值(调用迭代器的 hasNext() 和 next() 方法。
这是合成示例。
我有一个迭代器形式的生成器:
@RequiredArgsConstructor
static class TestIterator implements Iterator<Integer> {
private final int bound;
private final Random rnd = new Random();
private int current = 0;
@Override public boolean hasNext() {
return current < bound;
}
@Override public Integer next() {
current = rnd.nextInt(20);
System.out.println("Generated: " + current);
return current;
}
}
现在,我正在尝试拥有一个由少数迭代器组成的扁平流
public static void main(String... args) {
List<Iterator<Integer>> iterators = asList(
new TestIterator(18),
new TestIterator(18),
new TestIterator(18));
Stream<Integer> streams = iterators.stream()
.map(iter -> (Iterable<Integer>) () -> iter)
.flatMap(iter -> StreamSupport.stream(iter.spliterator(), false)) // <-- Here the stream of streams is flatten to a single stream of integers and 'parallel' is set to false
.limit(5); // <-- Here the limit is set
streams.forEach(i -> System.out.println("***Consumed: " + i));
}
而且,令我惊讶的是,输出如下:
Generated: 1
***Consumed: 1
Generated: 19
***Consumed: 19
Generated: 7
***Consumed: 7
Generated: 7
***Consumed: 7
Generated: 7
***Consumed: 7
Generated: 4
Generated: 3
Generated: 8
Generated: 14
Generated: 0
Generated: 16
Generated: 10
Generated: 3
Generated: 19
因此,Stream 生成的结果多于在 forEach 中传递给消费者的结果。即使它被明确设置为'parallel = false'。
在我的实际场景中,hasNext() 和 next() 函数非常昂贵,需要从外部服务获取数据。
谁能解释如何在限制结果方面做得更好?
提前致谢。
解决方案
这是一个已知的 JDK 错误,已在 JDK 10+ 中修复并向后移植到openjdk8u222
,因此更新您的 Java 版本将解决该问题。
推荐阅读
- scala - YAML azure-pipelines.yml 语法为所有步骤添加 azureSubscription
- ios - 将 UIView 动画与键盘动画同步
- asp.net-core - Blazor 中的自定义身份验证中间件 - 如何查看请求是否为匿名页面?
- swift - 更新 UIView heightAnchor
- tailwind-css - 您可以从顺风的边距和填充类中删除破折号吗?
- json - 如果子数组包含 n 次出现的带有 jq 的字符串,则排除对象
- python - Altair-即重复和变换
- data-structures - 在我的二进制堆/优先级队列实现中实现删除时遇到问题
- angular - 在 minikube 上部署 Angular App 并通过端口公开
- jsonschema - Understanding JSON Schema errors using ajv