Java Gold SE11対策:UnaryOperator・BinaryOperatorは何が違う

アイキャッチ画像

Java Gold SE11の試験では、ラムダ式とセットで使われる「UnaryOperator」「BinaryOperator」という関数型インタフェースが問題になることがあります。 これらはFunction、BiFunctionの特化型として存在しており、型が同じときに意図を明確にするために使われます。

● UnaryOperator

▶ 定義

@FunctionalInterface

public interface UnaryOperator<T> extends Function<T, T>

  • Function<T, R>の特化型
  • 引数も戻り値も同じT型

▶ 例

UnaryOperator<String> toUpper = s -> s.toUpperCase();

System.out.println(toUpper.apply(“java”)); // JAVA

▶ 使う利点

Function<T, T>でも同じことはできますが、型が同じであることを明示的にしたい場合にはUnaryOperatorを使うと可読性が高く意図が明確になります。

● BinaryOperator

▶ 定義

@FunctionalInterface

public interface BinaryOperator<T> extends BiFunction<T, T, T>

  • BiFunction<T, U, R>の特化型で、すべてT型
  • T × T → T の処理

▶ 例

BinaryOperator<Integer> sum = (a, b) -> a + b;

System.out.println(sum.apply(3, 5)); // 8

▶ 代表的な用途

  • 加算、最大値/最小値
  • String等の連続

BinaryOperator<String> concat = (a, b) -> a + b;

System.out.println(concat.apply(“Hello”, ” World”)); // Hello World

● Function/バリエーションとの関係

通常型特化型
Function<T, R>UnaryOperator
BiFunction<T, U, R>BinaryOperator (T=U=R)

→ すべての型が同じときに特化型を使うことで、意図を明確にできる。

● BinaryOperatorのstaticメソッド:maxBy / minBy

▶ 定義と目的

BinaryOperator には以下のようなstaticメソッドが存在します。

static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator)

static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator)

これは、2つの値を比較して大きい方/小さい方を返す処理を簡単に生成できるようにするファクトリメソッドです。

▶ 使用例:maxBy

BinaryOperator<String> longest =

    BinaryOperator.maxBy(Comparator.comparingInt(String::length));

System.out.println(longest.apply(“apple”, “banana”)); // banana

▶ 使用例:minBy

BinaryOperator<String> shortest =

    BinaryOperator.minBy(Comparator.comparingInt(String::length));

System.out.println(shortest.apply(“apple”, “banana”)); // apple

✅ 試験での要注意ポイント

観点ポイント
引数Comparator<? super T> が必要(Comparatorの仕組み理解必須)
戻り値BinaryOperator<T> を返す
型推論T の型が推論されるが、ラムダやメソッド参照と組み合わせるとやや複雑
使用シーンreduce() と合わせた出題パターンあり

⚠️ UnaryOperatorには static メソッドはない!

UnaryOperator は Function<T, T> の特化型ですが、maxByminBy のような static メソッドは提供されていません。その理由は:

  • 比較は「2つの値の関係性」を前提にしており、UnaryOperator(単項演算)には適していない
  • UnaryOperator の主な用途は「1つの値に対する変換」なので、比較ではなく変換が目的

● まとめ

名前概要元の型
UnaryOperatorT → TFunction<T, T>
BinaryOperatorT × T → TBiFunction<T, T, T>
  • Function、BiFunctionを使っていて「型が全部同じ」と気づいたら、Operatorに置き換えるのが良い
  • BinaryOperatorは maxBy, minBy などの便利メソッドあり

● おわりに

UnaryOperatorとBinaryOperatorは、どちらも型を明示的にすることでコードの可読性を高めることができます。Java Gold SE11の試験では、これらの特性を理解していることが問われます。絵面的に覚えるのではなく、「なぜそれを使うのか」を理解することが一番大切です。