コース一覧
    Java中級:Streamと関数型
    Stream を作る

    Java中級:Streamと関数型

    Stream APIと関数型インターフェースを学び、データ処理を宣言的で再利用しやすい形に書けるようにします。

    1
    Stream API
    01. Stream を作る5分
    02. filter で絞り込む5分
    03. map で変換する5分
    04. reduce で集約する5分
    05. collect で集める5分
    06. sorted で並び替え5分
    07. distinct で重複排除5分
    08. limit と skip5分
    09. 並列ストリーム5分
    10. Stream API まとめクイズ5分
    2
    関数型インターフェース
    01. ラムダ式の基本5分
    02. メソッド参照 ::5分
    03. Function インターフェース5分
    04. Predicate インターフェース5分
    05. Consumer と Supplier5分
    06. BiFunction と 2 引数の関数5分
    07. 関数型インターフェース まとめクイズ5分

    Stream を作る

    絞り込みや並べ替えのメソッドは、List には生えていない

    Java 8 で入った Stream API を使うと、コレクションの中身を「流れ」として扱い、絞り込みや並べ替えや集計をメソッドをつないで書けます。ただし、その便利なメソッドたちは List や Set そのものには生えていません。names.sorted() とは書けないのです。

    使うには、まずコレクションを Stream に変える必要があります。それが stream() です。

    Java

    List<String> names = List.of("Alice", "Bob", "Carol");
    Stream<String> stream = names.stream();

    stream() を呼んでも、元の names は何も変わりません。中身をコピーしているわけでもありません。「ここから 1 件ずつ流し出せます」という口を用意しただけです。Set も Map の values() も同じように stream() を持っているので、コレクションからの入り口はこれ 1 つで足ります。

    流れを作っただけでは、何も出てこない

    Stream は、作った時点では動きません。最後に終端操作と呼ばれるメソッドを呼んで、はじめて要素が流れ始めます。

    Java

    long count = names.stream().count();
    System.out.println(count);

    count() は要素数を返す終端操作です。戻り値が long になっているのは、Stream が数十億件規模のデータも扱う前提で設計されているからです。int の上限はおよそ 21 億なので、そこでは足りない場面があります。

    終端操作を書き忘れると、本当に何も起きません。エラーも出ません。これは遅延評価という仕組みで、途中の操作をつないだだけでは処理が始まらないようになっています。

    配列には stream() が無い

    int[] や String[] のような配列には stream() メソッドがありません。配列から流れを作るときは Arrays.stream を使います。

    Java

    import java.util.Arrays;
    
    int[] scores = {80, 95, 72};
    IntStream stream = Arrays.stream(scores);

    int[] を渡すと、返るのは Stream<Integer> ではなく IntStream です。sum() や average() のような数値専用のメソッドが使えるうえ、1 件ごとに Integer へ包み直す無駄も出ません。double[] なら DoubleStream、long[] なら LongStream が対応します。

    ここで Stream.of(scores) と書かないよう気をつけてください。Stream.of は Stream.of("a", "b", "c") のように値を並べるためのもので、配列を 1 つ渡すと「要素が 1 つだけ、その中身が配列」という妙な流れになってしまいます。

    流し終わった水は戻ってこない

    一度終端操作を呼んだ Stream は、二度と使えません。

    Java

    Stream<String> stream = names.stream();
    long a = stream.count();
    long b = stream.count();   // IllegalStateException

    2 回目で stream has already been operated upon or closed という実行時エラーになります。Stream は水そのものではなく水の流れなので、流れ終わったあとには何も残っていない、と考えると腑に落ちます。

    元のコレクションは手元に残っているので、必要なら names.stream() をもう一度呼べば済みます。Stream を変数に取っておかず、その場でつないで書き切るのが安全です。

    要件

    1. ファイル先頭で import java.util.Arrays; を書くこと
    2. Arrays.stream(arr) で IntStream を生成し、count() で要素数を取得すること
    3. count() の戻り値は long なので、(int) でキャストして int として return すること

    ヒント

    `int[]` から Stream を作るときは `Arrays.stream(arr)` を使います。`Stream.of(arr)` は型が違うので使えません

    `count()` の戻り値は `long` 型です。`int` 型のメソッドから返すには `(int)` でキャストが必要です

    空配列でも `Arrays.stream(arr).count()` は正常に動作し、`0` を返します。特別扱いは不要です

    生田 陸人
    監修生田 陸人
    ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
    編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

    関連レッスン

    • filter で絞り込む

      Java の Stream API の中でも最頻出の `filter` を取り上げ、ラムダ式で条件を渡して要素を絞り込み、`count` で個数を求めるコードを書いてみよう。

    • map で変換する

      Stream API の map を使って要素を別の値に変換する書き方を学び、IntStream.map との違いや mapToInt の使い分けまで踏み込んで身につけよう。

    • reduce で集約する

      Stream API の `reduce` を使って配列の要素を 1 つの値に畳み込む方法を学び、整数配列の積を求めるコードを書いてみよう。

    • collect で集める

      Stream の終端操作 collect と Collectors の代表的なファクトリ (toList, toSet, toMap, joining) を学び、filter で絞り込んだ要素を joining で文字列にまとめてみよう。

    このレッスンに出てくる用語

    意味があいまいなまま進んだ語は、ここから読み直せます。

    • メソッドクラスに属する関数
    • エンドポイント「この URL を叩くとこの機能が動く」入口の住所
    • APIアプリ間でデータをやり取りする窓口
    • 素数1 と自分自身でしか割り切れない自然数
    • 戻り値呼び出し元への返答を表す点線矢印
    • 設計何をどう作るかを決める前工程
    • 評価出力品質を数値化して継続改善する活動
    • 処理計算や代入を表す長方形
    main.java
    エディタを読み込んでいます

    メモ

    Stream を作る

    ⌘S で保存