9

Stream API を使用して Order インスタンスを生成しようとしています。注文を作成するファクトリ関数があり、DoubleStream を使用して注文の金額を初期化します。

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);

リテラル (1.0) を使用して Order インスタンスを初期化すると、これは正常に機能します。doubleStream を使用してランダムな量を作成すると、例外がスローされます。

4

6 に答える 6

15

答えはStream(私の強調)のjavadocにあります:

ストリームの操作 (中間または端末のストリーム操作の呼び出し) は 1 回だけにする必要があります。これにより、たとえば、同じソースが 2 つ以上のパイプラインにフィードする「フォークされた」ストリーム、または同じストリームの複数のトラバーサルが除外されます。ストリームの再利用が検出された場合、ストリームの実装は IllegalStateException をスローすることがあります

そして、あなたのコードでは、ストリームを 2 回使用します (1 回createOrder()と他の使用法は、.limit().forEach()

于 2015-01-16T18:36:24.363 に答える
4

他の回答で述べたように、Streams は使い捨てのアイテムであり、必要にStreamなるたびに新しいアイテムを作成する必要があります。

しかし、結局のところ、中間結果を保存する試みをすべて削除すれば、これは複雑ではありません。コード全体は次のように表現できます。

Random r=new Random(); // the only stateful thing to remember

// defining and executing the chain of operations:
r.doubles(50.0, 200.0).mapToObj(Order::new).limit(10).forEach(System.out::println);

またはさらに単純な

r.doubles(10, 50.0, 200.0).mapToObj(Order::new).forEach(System.out::println);
于 2015-01-16T19:59:09.440 に答える
0

あなたのメソッドは、代わりにこのようなワンライナーである可能性があります. mapToObjではなく、を使用する必要がありますmap

private List<Order> createOrders(int numberOfOrders) {
     return doubleStream.limit(numberOfOrders).mapToObj(Order::new).collect(Collectors.toList());
}
于 2015-01-16T21:55:36.173 に答える