Java 8 Stream IllegalStateException:流已经被操作或关闭

2022-01-22 00:00:00 data-generation java-8 java java-stream

我正在尝试使用 Stream API 生成 Order 实例.我有一个创建订单的工厂函数,一个 DoubleStream 用于初始化订单的金额.

private DoubleStream doubleStream = new Random().doubles(50.0, 200.0);私人订单 createOrder() {return new Order(doubleStream.findFirst().getAsDouble());}@测试公共无效测试(){流<顺序>orderStream = Stream.generate(() -> {返回创建订单();});orderStream.limit(10).forEach(System.out::println);

如果我使用文字 (1.0) 初始化 Order 实例,则可以正常工作.当我使用 doubleStream 创建一个随机量时,会抛出异常.

解决方案

答案在 Stream 的 javadoc 中(重点是我的):

<块引用>

一个流只能被操作一次(调用中间或终端流操作).例如,这排除了分叉"流,其中相同的源提供两个或多个管道,或者同一流的多次遍历.如果检测到流正在被重用,流实现可能会抛出 IllegalStateException.

在您的代码中,您确实使用了两次流(一次在 createOrder() 中,另一次在 .limit().forEach() 中使用p>

I'm trying to generate Order instances using the Stream API. I have a factory function that creates the order, and a DoubleStream is used to initialize the amount of the order.

private DoubleStream doubleStream = new Random().doubles(50.0, 200.0);

private Order createOrder() {
    return new Order(doubleStream.findFirst().getAsDouble());
}

@Test
public void test() {

Stream<Order> orderStream = Stream.generate(() -> {
    return createOrder();
});

orderStream.limit(10).forEach(System.out::println);

If I initialize the Order instance using a literal (1.0), this works fine. When I use the doubleStream to create a random amount, the exception is thrown.

解决方案

The answer is in the javadoc of Stream (emphases mine):

A stream should be operated on (invoking an intermediate or terminal stream operation) only once. This rules out, for example, "forked" streams, where the same source feeds two or more pipelines, or multiple traversals of the same stream. A stream implementation may throw IllegalStateException if it detects that the stream is being reused.

And in your code, you do use the stream twice (once in createOrder() and the other usage when you .limit().forEach()

相关文章