0Pricing
Java Academy · レッスン

プリミティブストリームの生成

iterate と generate です。

「プリミティブストリームの生成」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。

無限ストリームには制限が必要

iterateとgenerateは無限になる可能性のあるストリームを作成します。有限にするには、limit(または述語)を追加する必要があります。

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        IntStream.iterate(1, n -> n + 1)
            .limit(5)
            .forEach(System.out::println);
    }
}

シードを使った iterate

iterate(seed, next) はシードから開始し、直前の値に関数を繰り返し適用します。

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        IntStream.iterate(2, n -> n * 2)
            .limit(5)
            .forEach(System.out::println);
    }
}

述語を使った iterate

3引数版の iterate(seed, hasNext, next) は、述語が false になると自動的に停止します。関数型の for ループのように動作します。

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        IntStream.iterate(1, n -> n <= 100, n -> n * 3)
            .forEach(System.out::println);
    }
}

サプライヤーを使った generate

generate は、各要素を前の値に依存せず独立して生成する IntSupplier を受け取ります。

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        IntStream.generate(() -> 7)
            .limit(3)
            .forEach(System.out::println);
    }
}

乱数の生成

generate のサプライヤーから乱数の生成元を呼び出せます。ここでは各要素が独立したサイコロの出目です。

import java.util.Random;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        Random rnd = new Random(42);
        IntStream.generate(() -> rnd.nextInt(6) + 1)
            .limit(5)
            .forEach(System.out::println);
    }
}

iterate と generate の比較

主な違いは次のとおりです。

  • iterate: 各値は直前の値から導出されます(シーケンス)。
  • generate: 各値は独立して生成されます(定数や乱数)。
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        int sum = IntStream.iterate(1, n -> n + 1).limit(10).sum();
        System.out.println(sum);
    }
}

生成したストリームの集約

上限を設定すれば、生成したストリームでも通常の集約操作をすべて利用できます。

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        long count = IntStream.iterate(0, n -> n + 2)
            .limit(50)
            .filter(n -> n % 3 == 0)
            .count();
        System.out.println(count);
    }
}

オブジェクトストリームで iterate を使ったフィボナッチ数列

フィボナッチ数列のような状態を持つシーケンスでは、配列のペアに対して Stream.iterate を使い、その後 int に戻します。

import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        Stream.iterate(new int[]{0, 1}, p -> new int[]{p[1], p[0] + p[1]})
            .limit(8)
            .mapToInt(p -> p[0])
            .forEach(System.out::println);
    }
}

ジェネレーターから配列を構築する

ジェネレーターと toArray を組み合わせると、手続き的にプリミティブ配列を構築できます。

import java.util.Arrays;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        int[] squares = IntStream.iterate(1, n -> n + 1)
            .limit(5)
            .map(n -> n * n)
            .toArray();
        System.out.println(Arrays.toString(squares));
    }
}

遅延評価で処理量を削減

ストリームは遅延評価されます。そのため limit を使うと、無限のソースからでも必要な要素だけが生成されます。

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        int first = IntStream.iterate(10, n -> n + 10)
            .filter(n -> n > 25)
            .findFirst()
            .getAsInt();
        System.out.println(first);
    }
}

述語形式を優先する

述語ベースの iterate は、iterate(...).limit(...) よりも明確になることがよくあります。停止条件が生成ロジックと同じ場所にあるためです。

import java.util.stream.LongStream;

public class Main {
    public static void main(String[] args) {
        long product = LongStream.iterate(1, n -> n <= 5, n -> n + 1)
            .reduce(1, (a, b) -> a * b);
        System.out.println(product);
    }
}

確認問題

generate を limit なしで呼び出し、その後に forEach のような終端操作を実行するとどうなりますか。

まとめ

プリミティブストリームを生成しました。

  • iterate は各値を直前の値から導出します。
  • generate はサプライヤーから値を独立して生成します。
  • どちらも無限ストリームなので、limit または iterate の述語形式で範囲を制限します。
  • 遅延評価により、必要な要素だけが計算されます。

よくある質問

「プリミティブストリームの生成」レッスンは無料ですか?

はい。「プリミティブストリームの生成」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。

「プリミティブストリームの生成」で何を学びますか?

iterate と generate です。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Java Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「プリミティブストリームの生成」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このJava Academyレッスンでコードを書いて実行できますか?

はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

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

  1. IntStream と LongStream
  2. 範囲と集約操作
  3. Object ストリームとの相互変換
  4. プリミティブストリームの生成
← Java Academyに戻る