コース一覧
    Java中級:Streamと関数型
    map で変換する

    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分

    map で変換する

    入れ物を先に用意するのが面倒

    名前のリストから、それぞれの文字数のリストを作りたいとします。for で書くと、まず空のリストを用意するところから始まります。

    Java

    List<Integer> lengths = new ArrayList<>();
    for (String name : names) {
        lengths.add(name.length());
    }

    やりたいのは「文字数に変える」だけなのに、入れ物を作る行と、そこに詰める行が必要です。しかも lengths は宣言してから中身が入るまで空っぽの状態が続くので、途中で return を書き足すと未完成のリストが漏れます。

    map を使うと、変換の中身だけを書けば済みます。

    Java

    List<Integer> lengths = names.stream()
        .map(name -> name.length())
        .toList();

    map は個数を変えず、型だけ変える

    map に渡すのは「1 つ受け取って、1 つ返す」式です。要素ごとに 1 対 1 で入れ替えるので、3 件流せば必ず 3 件出てきます。件数を減らしたいときは filter の出番で、map は形の担当です。

    そのかわり、map は Stream の型を変えます。names は Stream<String> ですが、name.length() が返すのは数値なので、map を通した後は Stream<Integer> になります。元の型と違う型を返してよい、というのが map のいちばんの働きどころです。

    map は filter と同じ中間操作なので、書いただけでは何も起きません。toList() のような終端操作を呼んだときに、はじめて全要素が変換されます。

    数値の Stream には数値を返す

    IntStream にも map があります。摂氏の配列を華氏に直すなら、こう書けます。

    Java

    int[] fahrenheit = IntStream.of(celsius)
        .map(c -> c * 9 / 5 + 32)
        .toArray();

    ここで 1 つ、はまりやすい制限があります。IntStream の map は int を受け取って int を返す式しか受け付けません。

    Java

    IntStream.of(celsius).map(c -> c + " 度"); // コンパイルエラー

    数値の Stream から文字列や自作クラスに変えたいときは、map ではなく mapToObj を使います。逆に Stream<String> から数値の Stream に落としたいときは mapToInt です。名前が違うだけで、やっていることはどれも「1 つ受け取って 1 つ返す」で同じです。

    解説

    数値を数値のまま扱う IntStream には、合計や平均を出す終端操作がそろっています。Stream<Integer> にはこれらが無いので、数を集計するときは IntStream に寄せるのが定番です。

    やってみよう

    Solution.squareSum(int[] arr) を完成させて、各要素を 2 乗した合計を返してください。

    Arrays.stream(arr) で IntStream を作り、map に 2 乗する式を渡してから、合計を出す終端操作 sum() を呼びます。for を回して自分で足し込むのは禁止です。map で形を変えてから集計する、という流れをここで通しておいてください。

    戻り値は int で、sum() が返すのも int なので、今回はキャストは要りません。空配列を渡したときは、流れる要素が 1 つも無いので sum() の結果が 0 になります。長さを調べる if は不要です。

    要件

    1. Arrays.stream(arr) で int[] を IntStream に変換すること
    2. map(x -> x * x) を使って各要素を 2 乗する Stream の中間操作を使うこと (生の for ループで合計するのは NG)
    3. 終端操作 sum() を呼んで int の合計を return すること

    ヒント

    `Arrays.stream(int[])` の戻り値は `IntStream` です。`Stream<Integer>` ではないので、`mapToInt` を挟まずに `map(x -> x * x)` がそのまま使えます

    `IntStream.map` のラムダは `int -> int` の関数です。`x -> x * x` のように `int` を返す式を書きましょう

    空配列のときは `IntStream` が空になり、`sum()` は自動で `0` を返します。特別な分岐を書く必要はありません

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

    関連レッスン

    • reduce で集約する

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

    • collect で集める

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

    • sorted で並び替え

      Stream の sorted() で要素を昇順に並べ替え、Collectors.joining でカンマ区切り文字列に整形するテクニックを身につけよう。

    • distinct で重複排除

      Stream の `distinct()` で配列やリストから重複要素を取り除き、ユニークな要素数を集計する書き方を身につけよう。

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

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

    • リスト順序付きで複数の値を扱うデータ構造
    • 配列サイズ固定の同型データの集まり
    • クラスデータと振る舞いを束ねる単位
    • 戻り値呼び出し元への返答を表す点線矢印
    • instanceof「このオブジェクトの実際の型は何か」を確認 → 安全に変換
    • ループ繰り返し処理。矢印で戻すか専用記号で示す
    main.java
    エディタを読み込んでいます

    メモ

    map で変換する

    ⌘S で保存