コース一覧
    Java中級: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分

    ラムダ式の基本

    中身は 1 行なのに、まわりに 5 行付いてくる

    金額を表示用の文字列に整える処理を、後から差し替えられるようにしたいとします。Java でこれをやるには、まず入り口になるインタフェースを 1 つ用意します。

    Java

    interface Formatter {
        String format(int amount);
    }

    そして中身を渡します。Java 7 まではこう書くしかありませんでした。

    Java

    Formatter yen = new Formatter() {
        @Override
        public String format(int amount) {
            return amount + " 円";
        }
    };

    名前を付けないクラスをその場で作って渡す書き方で、匿名クラスと呼びます。書きたいのは amount + " 円" の 1 行だけなのに、new Formatter()、@Override、メソッドの宣言、閉じ括弧と、まわりに 5 行付いてきます。中身より外側の方が長い状態です。

    メソッドが 1 つなら、名前は書かなくても決まる

    よく見ると、この 5 行はどれも「書かなくても分かる」ものです。Formatter にはメソッドが 1 つしかないので、渡した中身がどのメソッドの実装なのかは、書かなくても決まります。型も、変数の宣言側に Formatter と書いてあります。

    Java 8 からは、その決まりきった部分を全部省けるようになりました。

    Java

    Formatter yen = amount -> amount + " 円";

    -> の左が引数、右が返す値です。これがラムダ式です。amount の型も書いていませんが、Formatter の format が int を受け取ると分かっているので、コンパイラが埋めてくれます。呼び方は匿名クラスのときと変わりません。

    Java

    System.out.println(yen.format(1200)); // 1200 円

    1 行で収まらないときは、{ } で囲んで return を書きます。

    Java

    Formatter taxIncluded = amount -> {
        int total = amount * 11 / 10;
        return total + " 円 (税込)";
    };

    書けるのは、メソッドが 1 つだけのインタフェース

    ラムダ式は、どんなインタフェースにも使えるわけではありません。メソッドが 1 つしかないインタフェースだけです。2 つあると、書いた中身がどちらの実装なのか決められないからです。

    自分で作るインタフェースには @FunctionalInterface を付けておくと安心です。うっかり 2 つ目のメソッドを足したときに、コンパイラが「これはもうラムダ式で書けない」と教えてくれます。

    解説

    Stream のメソッドが軒並みラムダ式を受け取れるのは、引数の型がすべてこの「メソッドが 1 つだけ」のインタフェースだからです。filter に渡していた n -> n > 0 も、sorted に渡していた比べ方も、正体はその場で作った実装でした。

    やってみよう

    Solution.lambdaSum(int[] arr) を static メソッドとして完成させて、配列の合計を返してください。

    Arrays.stream(arr) で作った IntStream を boxed() で Stream<Integer> に変え、mapToInt にラムダ式を渡してから sum() で合計を取ります。遠回りに見えますが、Stream<Integer> から数値の Stream に戻すところでラムダ式を 1 つ書く、という流れをここで通しておくためです。

    mapToInt に渡す式は、受け取った値をそのまま返すだけで足ります。空配列のときは合計が 0 になるので、長さを調べる if は要りません。

    要件

    1. Solution.lambdaSum(int[] arr) の static メソッドとして実装すること
    2. Arrays.stream(arr) で int[] を IntStream に変換し、.boxed() で Stream<Integer> に変えてから mapToInt(n -> n) でラムダ式を適用すること
    3. 最終的に sum() を呼んで合計を int で返すこと (空配列なら自動的に 0 が返る)

    ヒント

    ファイル先頭で `import java.util.Arrays;` を書くのを忘れないでください

    `IntStream` には `mapToInt` がないので、先に `.boxed()` で `Stream<Integer>` に変換してから `mapToInt(n -> n)` を呼びます

    ラムダ式 `n -> n` は「受け取った値をそのまま返す」恒等関数で、`Stream<Integer>` の `mapToInt` にそのまま渡せます

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

    関連レッスン

    • メソッド参照 ::

      ラムダ式をさらに短く書ける「メソッド参照 `Class::method`」の 4 種類と使い分けを学び、Stream + `String::toUpperCase` で文字列を大文字化して連結するコードを書いてみよう。

    • Function インターフェース

      Java の代表的な関数型インタフェース `Function<T, R>` を取り上げ、ラムダ式で値を変換する関数を作って `apply` で呼び出すコードを書いてみよう。

    • Predicate インターフェース

      Java の関数型インターフェースの代表格 `Predicate<T>` を取り上げ、`test` メソッドで条件を判定し、`and` `or` `negate` で条件を合成する書き方を身につけよう。

    • Consumer と Supplier

      java.util.function パッケージの代表的な関数型インターフェース Consumer と Supplier の役割と使い分けを学び、List.forEach や Stream.peek での活用までを身につけよう。

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

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

    • 処理計算や代入を表す長方形
    • クラスデータと振る舞いを束ねる単位
    • メソッドクラスに属する関数
    • 変数データに名前をつけて参照する仕組み
    • 引数位置引数=順番で渡す。
    • 配列サイズ固定の同型データの集まり
    main.java
    エディタを読み込んでいます

    メモ

    ラムダ式の基本

    ⌘S で保存