コース一覧
    Java中級:Streamと関数型
    Predicate インターフェース

    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分

    Predicate インターフェース

    if に書いた条件は、その場所から動かせない

    「このタグは有効か」という判定を、登録画面と一覧画面と集計処理の 3 か所で書いたとします。中身は同じ条件式なのに、if の中に直接書いてあるので共有できません。仕様が変わると 3 か所を探して直すことになり、1 か所直し忘れて挙動がずれる、というのがよくある事故です。

    条件そのものを変数に入れて持ち回せれば、直す場所は 1 か所で済みます。そのための型が java.util.function.Predicate<T> です。

    条件を変数に入れて、test で判定する

    Predicate<T> は「T を 1 つ受け取って true か false を返す」という意味の型です。動かす命令は test の 1 つだけで、戻り値は必ず boolean です。

    Java

    import java.util.ArrayList;
    import java.util.List;
    import java.util.function.Predicate;
    
    public class Demo {
        public static void main(String[] args) {
            Predicate<String> isBlank = s -> s.isBlank();
    
            System.out.println(isBlank.test("java"));   // false
            System.out.println(isBlank.test("   "));    // true
    
            List<String> tags = new ArrayList<>(List.of("java", "   ", "web"));
            tags.removeIf(isBlank);
            System.out.println(tags);                   // [java, web]
        }
    }

    tags.removeIf(isBlank) のところが大事です。List.removeIf は引数に Predicate を取る作りになっているので、自分で作った条件をそのまま渡せます。Stream の filter も同じです。条件に名前が付くと、読む側は中身を追わなくても何を選んでいるのか分かります。

    test が返せるのは boolean だけ

    つい「値を返すラムダ」を書いてしまうことがありますが、これはコンパイルエラーになります。

    Java

    Predicate<Integer> half = n -> n / 2;   // エラー、boolean ではない

    test の戻り値は boolean に固定されていて、それ以外の型は返せません。値を別の値に変える役目は Function が持っています。

    もう 1 つ、Predicate<int> とは書けません。ジェネリクスはプリミティブ型を受け取れないので、整数を判定するならラッパー型の Integer を書きます。

    Java

    Predicate<Integer> isEven = n -> n % 2 == 0;
    
    int size = 4;
    System.out.println(isEven.test(size));   // true

    size は int ですが、test に渡すところでオートボクシングが働くので、呼ぶ側で変換を書く必要はありません。

    解説

    条件が「1 つ受け取って真偽を返す」形になっているかどうかで判断します。真偽以外を返したくなった時点で、それは Predicate の仕事ではありません。

    課題では、判定の条件を Predicate の変数として作り、test を通した結果で数えます。if に条件式を直接書いても数は合いますが、それでは条件を取り出したことにならないので、必ず test を経由させてください。

    要件

    1. メソッドの中で Predicate<Integer> isPositive = n -> n > 0; をラムダ式で作ること
    2. 配列の各要素に対して isPositive.test(n) を呼び、true のものだけ数えること (if (n > 0) の直書きはせず、必ず Predicate を経由する)
    3. ファイル先頭で import java.util.function.Predicate; を書くこと

    ヒント

    `Predicate<T>` の抽象メソッドは `test(T)` の 1 個だけで、戻り値は `boolean` 固定です。`Predicate<Integer> isPositive = n -> n > 0;` のように書きます

    `for (int n : arr)` の `for-each` で回し、`if (isPositive.test(n)) { count++; }` のように数えるのが一番素直な書き方です

    `0` は正の数ではないので、`n > 0` であって `n >= 0` ではない点に注意してください

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

    関連レッスン

    • Consumer と Supplier

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

    • BiFunction と 2 引数の関数

      2 つの引数を受け取って 1 つの値を返す BiFunction、同じ型同士を扱う BinaryOperator、そして BiPredicate / BiConsumer といった「2 引数版」の関数型インターフェースを整理し、引数が複数あるラムダの書き方を身につけよう。

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

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

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

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

    • 処理計算や代入を表す長方形
    • 変数データに名前をつけて参照する仕組み
    • 戻り値呼び出し元への返答を表す点線矢印
    • 引数位置引数=順番で渡す。
    • コンパイルソースをバイトコードへ変換する処理
    • ジェネリクス<String> のように型を指定する仕組み
    • プリミティブnumber / string / boolean などの基本型
    • プリミティブ型Javaの基本型(int/double/boolean等)
    main.java
    エディタを読み込んでいます

    メモ

    Predicate インターフェース

    ⌘S で保存