iterateとgenerateによる無限ストリーム
Stream.iterateとStream.generateで無限ストリームを作成し、limitまたはtake-whileで停止させます。
「iterateとgenerateによる無限ストリーム」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。
無限ストリームとは
Javaストリームは無限にすることができ、終わりなく要求に応じて要素を生成します。無限に実行され続けるのを避けるため、制限操作(limit、takeWhile、findFirstなど)で終端させる必要があります。
Stream.iterate: シードから始まるシーケンス
Stream.iterate(seed, f)は、前の値にfを繰り返し適用して無限ストリームを生成します。最初の要素はシードです。
// Infinite even numbers: 0, 2, 4, 6, 8, ...
Stream.iterate(0, n -> n + 2)
.limit(10)
.forEach(System.out::println);Predicate付きiterate(Java 9以降)
Stream.iterate(seed, predicate, f)は、forループの条件のような停止条件を追加します。predicateがfalseになると、ストリームは停止します。
// Equivalent to: for (int i = 1; i <= 100; i *= 2)
Stream.iterate(1, n -> n <= 100, n -> n * 2)
.forEach(System.out::println); // 1 2 4 8 16 32 64Stream.generate: ステートレスなジェネレーター
Stream.generate(Supplier)は、各要素に対してsupplierを呼び出します。supplierはステートレス(乱数など)にも、ステートフル(外部カウンターを使用する場合など)にもできます。
// Infinite random doubles between 0.0 and 1.0:
Stream.generate(Math::random)
.limit(5)
.forEach(System.out::println);UUIDを生成する
generateとUUID::randomUUIDを使用すると、一括でIDを生成するための一意な識別子のストリームを作成できます。
List<String> ids = Stream.generate(() -> UUID.randomUUID().toString())
.limit(100)
.collect(Collectors.toList());
System.out.println(ids.size()); // 100iterateによるフィボナッチ数列
状態としてペアを使用して、フィボナッチ数を生成します。Java 9の2引数版iterateを使うと、簡潔に記述できます。
Stream.iterate(new long[]{0, 1}, p -> new long[]{p[1], p[0]+p[1]})
.limit(10)
.map(p -> p[0])
.forEach(System.out::println); // 0 1 1 2 3 5 8 13 21 34takeWhileとdropWhile(Java 9以降)
takeWhile(predicate)はpredicateがtrueである間要素を取得し、その後停止します。dropWhileはpredicateがfalseになるまで要素をスキップし、その後の残りを取得します。
// takeWhile stops at the first element where predicate is false:
Stream.iterate(1, n -> n + 1)
.takeWhile(n -> n < 10)
.forEach(System.out::println); // 1 2 3 4 5 6 7 8 9再試行ポーリングのための無限ストリーム
generateでポーリングループをモデル化できます。チェック結果を生成し、条件が満たされていない間はtakeWhileで取得し続け、その後最初に成功した結果を取得します。
Optional<String> result = Stream.generate(() -> checkJobStatus(jobId))
.takeWhile(status -> status.equals("PENDING"))
.findFirst();
// When job completes, takeWhile stops and findFirst gets "DONE"IntStream.rangeとrangeClosed
有限の整数シーケンスには、IntStream.range(start, end)とrangeClosed(start, end)を使用すると、iterateより効率的です。
// Sum 1 to 1000:
int sum = IntStream.rangeClosed(1, 1000).sum();
System.out.println(sum); // 500500Longシーケンス用のLongStream.iterate
LongシーケンスにはLongStream.iterateを使用すると、Stream<Long>のオートボクシングによるオーバーヘッドを避けられます。
long sumOfPrimes = LongStream.iterate(2, n -> n + 1)
.filter(n -> isPrime(n))
.limit(1000)
.sum();無限ストリームは遅延評価される
無限ストリームは要素を事前に計算しません。終端操作が要求したときにだけ、各要素が生成されます。この遅延評価によって、無限ストリームを実用的に利用できます。
確認問題
無限ストリームを扱うとき、どのような停止の仕組みが必要ですか。
振り返り
シーケンスにはiterate(seed, f)、独立した要素の生成にはgenerate(supplier)を使用します。必ず短絡する終端操作(limit、takeWhile、findFirst)を追加してください。無限ストリームは遅延評価され、要求されたときにだけ具体化されます。
よくある質問
「iterateとgenerateによる無限ストリーム」レッスンは無料ですか?
はい。「iterateとgenerateによる無限ストリーム」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。
「iterateとgenerateによる無限ストリーム」で何を学びますか?
Stream.iterateとStream.generateで無限ストリームを作成し、limitまたはtake-whileで停止させます。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Java Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「iterateとgenerateによる無限ストリーム」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このJava Academyレッスンでコードを書いて実行できますか?
はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- ネストしたコレクションに対するflatMap
- 並列ストリーム:性能と注意点
- Spliterator:並列処理のための分割
- iterateとgenerateによる無限ストリーム