IntStream / LongStream / DoubleStream(プリミティブストリーム) — オートボクシング回避
Java の Stream API には、Stream<Integer> や Stream<Double> のような「ラッパークラスのストリーム」だけでなく、プリミティブ専用のストリームがあります。
それが IntStream / LongStream / DoubleStream。これを使うと オートボクシング(int → Integer などの変換)を避けられるため、速度とメモリ効率が良くなります。
基本の特徴
- IntStream:
int専用のストリーム。 - LongStream:
long専用のストリーム。 - DoubleStream:
double専用のストリーム。
メリット
- オートボクシング不要 → 無駄なオブジェクト生成が減る。
- 専用の集計メソッドあり →
sum(),average(),max(),min()などが直接使える。 - 数値範囲生成が簡単 →
IntStream.range,IntStream.rangeClosedなど。
基本コード例
IntStream の利用
import java.util.stream.*;
public class IntStreamExample {
public static void main(String[] args) {
int sum = IntStream.range(1, 6) // 1〜5
.sum();
System.out.println(sum); // 15
}
}
JavaLongStream の利用
long product = LongStream.rangeClosed(1, 5) // 1〜5
.reduce(1, (a, b) -> a * b);
System.out.println(product); // 120
JavaDoubleStream の利用
DoubleStream ds = DoubleStream.of(1.5, 2.5, 3.5);
double avg = ds.average().orElse(0.0);
System.out.println(avg); // 2.5
Java例題で理解する
例題1: 1〜100 の合計(IntStream)
int total = IntStream.rangeClosed(1, 100).sum();
System.out.println(total); // 5050
Java- ポイント:
sum()が直接使えるので簡潔。
例題2: 配列の平均値(DoubleStream)
double[] temps = {36.5, 37.2, 36.8, 37.0};
double avg = DoubleStream.of(temps).average().orElse(0.0);
System.out.println("平均温度=" + avg); // 平均温度=36.875
Java- ポイント:
average()は OptionalDouble を返すのでorElseで安全に扱う。
例題3: 偶数だけ抽出して平方和(IntStream)
int result = IntStream.rangeClosed(1, 10)
.filter(n -> n % 2 == 0) // 偶数だけ
.map(n -> n * n) // 平方に変換
.sum(); // 合計
System.out.println(result); // 220 (2²+4²+6²+8²+10²)
Java- ポイント: filter → map → sum の流れが自然。
例題4: LongStream で大きな範囲を扱う
long count = LongStream.rangeClosed(1, 1_000_000)
.filter(n -> n % 100_000 == 0)
.count();
System.out.println(count); // 10
Java- ポイント: long 専用なので大きな範囲でも安全。
テンプレート集
- 範囲生成
IntStream.range(start, end); // start〜end-1
IntStream.rangeClosed(start, end); // start〜end
Java- 配列から生成
IntStream.of(array);
DoubleStream.of(array);
Java- 集計
int sum = IntStream.of(1,2,3).sum();
double avg = DoubleStream.of(1.0,2.0).average().orElse(0.0);
long max = LongStream.of(10,20).max().orElse(Long.MIN_VALUE);
Java- 変換
IntStream.range(1,10).map(n -> n*n).toArray();
Java- reduce
long product = LongStream.rangeClosed(1,5).reduce(1, (a,b) -> a*b);
Java落とし穴と回避策
- Optional 型の扱い:
average(),max(),min()は Optional 型を返す。空ストリームなら値がないのでorElseを必ず使う。 - Boxed 変換: プリミティブストリームを
Stream<Integer>に変換したい場合は.boxed()を使う。 - 大きな範囲: IntStream は
intの範囲まで。より大きな範囲は LongStream を使う。
まとめ
- IntStream / LongStream / DoubleStream はプリミティブ専用のストリームで、オートボクシングを避けて効率的。
sum,average,max,minなどの便利メソッドが直接使える。- 範囲生成や配列処理に強く、数値計算や統計処理に最適。
👉 練習課題: 「1〜1000 の偶数の平均値を IntStream で求める」コードを書いてみると、プリミティブストリームの便利さが体感できます。
