0Pricing
Java Academy · レッスン

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 64

Stream.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()); // 100

iterateによるフィボナッチ数列

状態としてペアを使用して、フィボナッチ数を生成します。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 34

takeWhileと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); // 500500

Longシーケンス用の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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. ネストしたコレクションに対するflatMap
  2. 並列ストリーム:性能と注意点
  3. Spliterator:並列処理のための分割
  4. iterateとgenerateによる無限ストリーム
← Java Academyに戻る