【Java】Arrays.streamとStream.ofの違い

目次

はじめに

Javaで配列を扱う際、「配列をストリーム(Stream)に変換したい」というケースはよくあります。そんなときによく使われるのが Arrays.stream()Stream.of() の2つのメソッドです。

一見似ているこの2つですが、使い方を誤ると「配列の中身を処理したいのに配列そのものが1つの要素になってしまう」といった落とし穴があります。パフォーマンスやバグの観点からも、両者の違いを正しく理解することは非常に重要です。

この記事では、Arrays.stream()Stream.of()の本質的な違いと、どちらを選ぶべきかの判断基準を、具体的なコード例を交えてわかりやすく解説します。

結論:配列の要素を処理したいなら Arrays.stream 一択

まず最初に押さえておくべき結論はシンプルです。

  • 配列の中身(各要素)をストリーム処理したい場合は、Arrays.stream() を使うのが正解です。
  • Stream.of()配列全体を「1つの要素」として扱うため、要素ごとの処理には不向きです。

この違いを理解していないと、「ループが1回しか回らない」「要素が出力されない」といった意図しない挙動につながる可能性があります。迷ったときは、「何をストリームにしたいのか?」を明確にし、用途に合ったメソッドを選びましょう。

Arrays.streamの使い方と特徴

Arrays.stream()配列からストリームを生成するための専用メソッドです。特に配列の中身を1つずつ処理したい場合に適しています。

int[] nums = {1, 2, 3};
IntStream stream = Arrays.stream(nums);
stream.forEach(System.out::println);  // 出力: 1, 2, 3

主な特徴

  • 各配列要素をそのままストリーム要素に変換
  • プリミティブ型(int[], double[]など)にも対応
  • IntStreamDoubleStreamなどのプリミティブ用のストリームが生成されて効率的

メリット

  • ボクシング不要なので高速(例:intInteger の変換が不要)
  • sum(), average(), max() など、集約系の処理が豊富

Arrays.stream() は、配列の内容をストリーム処理したいときの基本かつ最適な選択肢です。特にプリミティブ型の配列を扱う場面では、その恩恵を最大限に受けることができます。

Stream.ofの使い方と特徴

Stream.of() は、複数の値やオブジェクトを手軽にストリーム化できるユーティリティメソッドです。可変長引数(varargs)に対応しており、指定した値をそのままストリームの要素として扱えます。

Stream<String> stream = Stream.of("A", "B", "C");
stream.forEach(System.out::println);  // 出力: A, B, C

主な特徴

  • 可変長引数(Varargs)を受け取るため、複数の要素を直接指定できる
  • 配列を渡した場合、その配列全体が1つの要素として扱われる

注意点:配列の扱い

int[] nums = {1, 2, 3};
Stream<int[]> stream = Stream.of(nums);
stream.forEach(System.out::println);  // 出力: [I@6073f712

このように、配列を渡しても中身は展開されず、配列オブジェクトそのものが1要素になります。

String[] strs = {"A", "B", "C"};
Stream<String> stream = Stream.of(strs);
stream.forEach(System.out::println);  // 出力: A, B, C

参照型の配列(String[]など)を Stream.of() に渡すと期待通りになります。

これは内部的に Arrays.stream() が呼び出されているわけではなく、Stream.of(T... values)TString で、可変長引数として展開されているためです。つまり、Stream.of(strs) と書いた場合、Javaは Stream.of("A", "B", "C") と同じ意味に解釈してくれます(参照型の配列はvarargsとして展開されるため)。

プリミティブ配列との違いで混乱することを避けるため、配列からStreamへの変換はArrays.stream() を利用することをおすすめします。

使い分け早見表と判断基準

Arrays.stream()Stream.of() はどちらも配列をストリームに変換できますが、目的に応じて使い分ける必要があります。以下の早見表を参考に、最適なメソッドを選びましょう。

やりたいこと使うメソッド理由・特徴
配列の各要素をストリームに変換したいArrays.stream()各要素が1つずつストリームに展開される
配列全体を1つの要素として扱いたいStream.of()配列全体が1つの要素になる
複数の値を直接指定してストリームにしたいStream.of()可変長引数で任意の数の値を渡せる
プリミティブ型配列を効率よく処理したいArrays.stream()IntStream などが生成され高速

ポイントは「配列の中身を処理したいのか、配列そのものを扱いたいのか」です。用途に応じて正しいメソッドを選ぶことで、バグのない意図どおりのコードを書くことができます。

まとめ:ストリーム生成は目的に応じて正しく使い分けよう

JavaのStream APIは非常に強力ですが、その分使い方を誤ると予期しない挙動になることもあります。

配列をストリームに変換したいなら Arrays.stream()、ストリームを直接生成もしくは配列全体を1つの要素として扱いたいなら Stream.of()。この基本ルールを覚えておくだけで、コードの明確さと安全性が大きく向上します。

ストリーム生成時は「何をストリームに変換したいのか?」を明確にし、それに合ったメソッドを選びましょう。そうすることで、バグのない明確でメンテナンス性の高いコードを書くことができます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次