プリミティブストリームの生成
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フィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- IntStream と LongStream
- 範囲と集約操作
- Object ストリームとの相互変換
- プリミティブストリームの生成