ホーム › 関数型プログラミング › Func-01
Func-01: java.util.function パッケージの関数型インターフェース
Java 8 で導入された java.util.function パッケージには、 関数をオブジェクトとして扱うための「関数型インターフェース」が揃っています。 Stream API やラムダ式と組み合わせて使うことで、簡潔で読みやすいコードが書けます。
4種類の基本インターフェース
java.util.function パッケージには 40種類以上のインターフェースがありますが、基本となるのは以下の4種類です。 これらを組み合わせることで、ほとんどのユースケースに対応できます。
| インターフェース | 型シグネチャ | 呼び出しメソッド | 主な用途 |
|---|---|---|---|
Function<T, R> | T → R | apply(T t) | 型変換・マッピング |
Consumer<T> | T → void | accept(T t) | ログ出力・画面表示・副作用 |
Supplier<T> | () → T | get() | 遅延生成・ファクトリ |
Predicate<T> | T → boolean | test(T t) | フィルタリング・条件判定 |
関数合成のデフォルトメソッド
Function.andThen(f): 元の関数を適用した後に f を適用します(「AをしてからBをする」)Function.compose(f): f を先に適用してから元の関数を適用します(andThen の逆順)Predicate.and(p): 両方の条件が true のとき true を返しますPredicate.or(p): どちらか一方が true のとき true を返しますPredicate.negate(): 条件を反転します(true ↔ false)
サンプルコード
Java 8 で java.util.function パッケージが導入されました。Function・Consumer・Supplier・Predicate の4種類が基本です。andThen() や and()/or() などのデフォルトメソッドで関数を合成できます。
よくあるミス・注意点
⚠️ Consumer で戻り値を期待してしまう(戻り値は void)
Consumer<T> のaccept() はvoid を返します。 「処理した結果を受け取りたい」場合は Function<T, R> を使ってください。 Consumer はログ出力や画面表示など「値を渡して何かをするが結果は不要」なときに使います。
⚠️ Predicate.and() と && の違い(ショートサーキット評価)
Predicate.and() も&& と同様にショートサーキット評価(左辺が false なら右辺を評価しない)を行います。 ただし、and() を使うと Predicate をオブジェクトとして渡したり組み合わせたりできるため、 Stream の filter() に直接渡すときに便利です。 一方、ラムダ式の中に直接 && を書くほうが読みやすいこともあります。 使い分けのポイントは「Predicate を再利用・合成したいかどうか」です。
テストする観点
Function.andThen()で合成した関数が、単独適用を順番に行った結果と一致することPredicate.and()の結果が、手書きの&&と同じ真偽値を返すこと(境界値: どちらかが false のとき)Predicate.or()の結果が、||と同じ真偽値を返すことSupplierのget()が呼ばれるたびに新しいインスタンスを返すこと(遅延評価の確認)BiFunctionが2引数を受け取り期待通りの結果を返すこと