このJavaコードのコメントアウト版は以下の通りです。答えがA、つまりPredicate<Sample>
である理由も説明します。
import java.util.Arrays;
import java.util.List;
import java.util.function.*; public class Main { public static void main(String[] args) { // Sampleオブジェクトのリストを作成 List<Sample> list = Arrays.asList( new Sample(10), new Sample(20), new Sample(30)); // xに対してtestメソッドを適用し、条件を満たすかチェック if (x.test(new Sample(20))) { System.out.println("ok"); } }
} // Sampleクラスの定義
class Sample { private int num; // Sampleの数値を保持するフィールド public Sample(int num) { this.num = num; // コンストラクタで数値を初期化 } // オブジェクトが等しいかどうかを評価するequalsメソッド public boolean equals(Object obj) { // オブジェクトがSample型ではない場合、falseを返す if (obj instanceof Sample == false) { return false; } // 数値が同じであればtrueを返す if (this.num == ((Sample)obj).num) { return true; } // 上記の条件に合致しない場合はfalseを返す return false; }
}
A. Predicate<Sample>
x = s -> list.contains(s);
これが正しい答えです。Predicateは、引数を取って何らかの条件で評価を行い、boolean値を返す関数型インタフェースです。ここでは、与えられたSample
オブジェクトがリストに含まれているかどうかを確認しています。test
メソッドはこの確認を行い、new Sample(20)
がリストに含まれているかどうかを評価します。含まれていればtrue
を返し、main
メソッド内のif
ステートメントで”ok”が出力されます。
その他の選択肢は以下の理由で不適切です:
B. Supplier<Sample>
は結果を供給するが、条件をテストしない。
C. Consumer<Sample>
は引数を消費するが、何かを戻すわけではなくテストもしない。
D. Function<Sample>
は一つの型から別の型への変換を行うが、単に条件をテストするだけではない。
追記
画像内のテキストは以下の通りです:
[関数型インタフェースの特徴]
関数型インタフェース | メソッド | 説明 |
---|---|---|
Consumer | void accept(T) | 引数を受け取って処理をする。結果を戻さない、引数の「消費者」 |
Supplier | T get() | 何も受け取らずに結果だけを戻す「供給者」 |
Predicate | boolean test(T) | 引数を受け取ってそれを評価する「断定」 |
Function | R apply(T) | 引数を受け取って、指定された型(R) の結果を戻す「処理」 |
ポイント
極簡単なコツをお伝えします。このJavaのコードにおいて、正しい関数型インタフェースを選ぶためには、以下のステップに従うとよいでしょう:
メソッドのシグネチャを理解する:
-
boolean test(T t)
:何かを受け取り、boolean
の結果を返す(Predicate
)。 -
T get()
:何も受け取らずに、何かを返す(Supplier
)。 -
void accept(T t)
:何かを受け取り、返り値がない(Consumer
)。 -
R apply(T t)
:何かを受け取り、別の型の何かを返す(Function
)。
-
コードが何を求めているかを理解する:
- この場合、
if (x.test(new Sample(20))) { ... }
は、x
が何かの条件をテストしていることを示しています。
- この場合、
メソッドのシグネチャとコードの要求を照合する:
- コードがテストを行っているので、返り値の型が
boolean
である関数型インタフェースを探します。 -
test(T t)
メソッドを持つのはPredicate
インタフェースだけです。
- コードがテストを行っているので、返り値の型が
この3ステップにより、選択肢AがPredicate<Sample>
である理由がわかります。なぜなら、list.contains(s)
はboolean
値を返し、これはPredicate
のtest
メソッドの契約に合致しているからです。他のインタフェースは、この使用方法に合致しないシグネチャを持っています。