コース一覧
    Java中級:Streamと関数型
    BiFunction と 2 引数の関数

    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分

    BiFunction と 2 引数の関数

    引数が 2 つになったとたん、Function では受けられない

    Function<T, R> の apply は引数を 1 つしか取りません。ところが実際に渡したい処理は、姓と名をつなぐ、単価と個数から金額を出す、といった 2 引数のものが山ほどあります。

    Function<String, String> f = (last, first) -> last + first; と書いてもコンパイルは通りません。ラムダの引数の数が、インタフェースが決めている数と合わないからです。引数を 2 つ受け取りたいなら、最初から 2 つ受け取る型を選びます。それが java.util.function.BiFunction<T, U, R> です。

    型は「入力 2 つ」と「出力 1 つ」で 3 つ書く

    BiFunction<T, U, R> は「T と U を受け取って R を返す」という意味です。<> の中は入力が 2 つ並んで、最後が戻り値です。動かす命令は Function と同じ apply で、こちらは引数を 2 つ渡します。

    Java

    import java.util.function.BiFunction;
    
    public class Demo {
        public static void main(String[] args) {
            BiFunction<String, String, String> fullName = (last, first) -> last + " " + first;
            BiFunction<String, Integer, String> repeat = (text, times) -> text.repeat(times);
    
            System.out.println(fullName.apply("山田", "花子"));  // 山田 花子
            System.out.println(repeat.apply("ab", 3));           // ababab
        }
    }

    fullName は 3 つとも String、repeat は入力の 2 つ目だけ Integer です。入力の型は揃っていなくて構いません。ここで型を 2 つしか書かず BiFunction<String, String> としてしまうと「型パラメータが足りない」というエラーになります。戻り値の分を数え忘れるのが定番のつまずきです。

    なお、入力 2 つと出力がすべて同じ型になるときは、BinaryOperator<T> という短い別名も使えます。書き味は同じで、型を 1 つ書くだけで済みます。

    引数が 2 つ以上のラムダは、かっこを省けない

    引数が 1 つのラムダは s -> s.trim() のようにかっこを省略できますが、2 つ以上では省略できません。

    Java

    BiFunction<String, String, String> ng = last, first -> last + first;   // 文法エラー
    BiFunction<String, String, String> ok = (last, first) -> last + first; // これが正しい

    Java

    BiFunction<String, String, Boolean> sameLength = (a, b) -> a.length() == b.length();
    System.out.println(sameLength.apply("java", "html"));   // true

    incompatible types や Lambda expression not expected here というエラーが出たときは、たいていインタフェースが決めている引数の数と、ラムダに書いた引数の数がずれています。まず両方の数を数え直すのが早道です。

    解説

    標準ライブラリに用意されているのは 2 引数までです。TriFunction を import しようとしても見つかりません。3 つ以上になったら、引数をひとまとめにしたレコードを作って 1 引数に畳むのが実務では読みやすくなります。

    課題では BiFunction の変数を作り、apply に 2 つの引数を渡した結果を返します。計算を直接 return しても数字は合いますが、apply を経由させることが今回の目的です。

    要件

    1. ファイル先頭で import java.util.function.BiFunction; を書くこと
    2. メソッド本体で BiFunction<Integer, Integer, Integer> 型の変数を (x, y) -> x + y のラムダで初期化すること
    3. sum.apply(a, b) のように apply を呼び出した戻り値を return すること (直接 a + b を返さない)

    ヒント

    `BiFunction` の型パラメータは `<引数1, 引数2, 戻り値>` の **3 個** です。`BiFunction<Integer, Integer>` のように 2 個にすると型エラーになります

    2 引数のラムダは `(x, y) -> x + y` のようにかっこが必須です。`x, y -> x + y` と書くと文法エラーです

    `apply` の戻り値は `Integer` ですが、`return` する変数の型が `int` なら **オートアンボクシング** で自動変換されるのでキャストは不要です

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

    関連レッスン

    • 関数型インターフェース まとめクイズ

      関数型インターフェース (Lambda / メソッド参照 / Function / Predicate / Consumer / Supplier / BiFunction) の総まとめ。代表的な 7 つの関数型インターフェースの違いを 4 択クイズで確認する。

    • Consumer と Supplier

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

    • Predicate インターフェース

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

    • Function インターフェース

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

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

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

    • 引数位置引数=順番で渡す。
    • 処理計算や代入を表す長方形
    • コンパイルソースをバイトコードへ変換する処理
    • 戻り値呼び出し元への返答を表す点線矢印
    • 標準ライブラリPythonに同梱の公式モジュール群
    • レコードテーブル内の1件分のデータ(行)
    • 変数データに名前をつけて参照する仕組み
    • メソッドクラスに属する関数
    main.java
    エディタを読み込んでいます

    メモ

    BiFunction と 2 引数の関数

    ⌘S で保存