web-dev-qa-db-ja.com

述語とifステートメント

以下の簡単な例で示すように、人々が純粋なifステートメントの代わりにPredicatesを使用するプロジェクトをいくつか見ました。

    int i = 5;
    // Option 1
    if (i == 5) {
        // Do something
        System.out.println("if statement");
    }

    // Option 2
    Predicate<Integer> predicate = integer -> integer == 5;
    if (predicate.test(i)) {
        // Do something
        System.out.println("predicate");
    }

IfステートメントよりもPredicatesを使用する利点は何ですか?

16
poyger

あなたが提供したexactの例の場合、述語を使用することは大きなやりすぎです。コンパイラーとランタイムは次のものを作成します。

  1. メソッド(脱糖述語)
  2. java.util.Predicateを実装する.class
  3. 2で作成されたクラスのインスタンス

これらすべてと単純なifステートメントとの比較。

そしてこれがステートレスな述語のためのすべてです。述語がステートフルの場合、次のようになります。

 Predicate<Integer> p = (Integer j) -> this.isJGood(j); // you are capturing "this"

その後、この述語を使用するたびに、新しいインスタンスが作成されます(少なくとも現在のJVMの下)。

そのような述語を作成するための唯一の実行可能なオプションIMOは、もちろん、それを複数の場所で再利用することです(メソッドへの引数として渡すなど)。

18
Eugene

述語を使用すると、コードがより柔軟になります。

常にi == 5かどうかをチェックする条件を記述する代わりに、Predicateを評価する条件を記述できます。これにより、さまざまなPredicatesを渡して、さまざまな条件を実装できます。

たとえば、Predicateは引数としてメソッドに渡すことができます。

public void someMethod (Predicate<Integer> predicate) {
    if(predicate.test(i)) {
        // do something
        System.out.println("predicate");
    }
    ...
}

これがfilterStreamメソッドの仕組みです。

17
Eran

Ifステートメントの使用は、バイナリ条件をチェックするための最良の(読み取り:最もパフォーマンスの高い)方法です。

Switchステートメントは、より複雑な状況ではより高速になる場合があります。

PredicateFunctionの特殊な形式です。実際、Java言語アーキテクトは、一般的なプリミティブ型を許可する方法に取り組んでいます。これにより、Predicate<T>Function<T, boolean>とほぼ同等になります(テスト対適用メソッド名をモジュロ化) 。

関数(またはメソッド)が1つ以上の関数を引数として取る場合、それを高次関数と呼びます。関数にbehaviourを渡していると言います。これにより、強力なAPIを作成できます。

String result = Match(arg).of(
        Case(isIn("-h", "--help"),    help()),
        Case(isIn("-v", "--version"), version()),
        Case($(),                     cmd -> "unknown command: " + cmd)
);

この例は、Java 8+のオブジェクト関数型プログラミングのライブラリ Javaslang から引用しています。

免責事項:私はJavaslangの作成者です。

0
Daniel Dietrich