2017-02-15 1 views
0

私は次のコードを持っている:それは方法は、最初の引数で呼び出さなっている「含まれ」と二番目の引数が渡されていることがいかに声明listContains.test(aListの、20)では、Java 8 BiPredicateが最初の引数でメソッドを自動的に呼び出しますか?

public class BiPredicateTest { 
    public static void main(String[] args) { 
     BiPredicate<List<Integer>, Integer> listContains = List::contains; 
     List aList = Arrays.asList(10, 20, 30); 
     System.out.println(listContains.test(aList, 20));  // prints true magically? 
    } 
} 

をパラメータとして?同等の何か:つまり

System.out.println(aList.contains(20)); 

は、どのように声明listContains.test(aListの、20)がaList.contains(20)に変換されますでしょうか?

これはJava 8 BiPredicateの仕組みですか?誰かが魔法がどのように起こっているのかを説明することができますか?

これは重複した投稿ではありません。これは、Java 8では「特定の型の任意のオブジェクト」が意味する「何か」とは異なりますか?明示的に渡すメソッドではなく、そのメソッドを参照しています。あなたが参照する投稿の中でメソッド参照がどのように渡されているかは非常に明確です。メソッドが呼び出されている配列インスタンスは、引数としてArrays.sort()に渡されます。私の場合、どのようにメソッドが "含まれている" aListに呼び出されているかは明らかではありません。私はその働き方についての参考や説明を探しています。

参照や説明の代わりに投票を辞退したい人もいます。彼らは知識を持っているが、それを共有することを拒否しているという印象を与える。

+3

「BiPredicate」に固有のものではありません。メソッド参照がどのように機能するかを調べることができます。 – 4castle

+0

@ 4castle返信いただきありがとうございます。 BiPredicateリファレンス 'listContains'で 'test'メソッドを呼び出すと、List :: containsメソッドが呼び出されることを理解しています。しかし、それが呼び出されるオブジェクトはどのように選択されますか(この例ではaList)?この例では完全にはっきりしていません。 BiPredicateを使用しない例がありますか? – Ali

+1

[参考資料](http://moandjiezana.com/blog/2014/understanding-method-references/)が便利です。 「Desugaring Lambdas」のセクションを見てください。 – Enwired

答えて

2

BiPredicateは、1つのメソッドtestを持つインターフェイスです。

public interface BiPredicate<A,B> { 
    boolean test(A a, B b); 
} 

1つの方法しかないインターフェイスを機能インターフェイスと呼びます。 Java 8より前のバージョンでは、匿名クラスを使用してこれらのインタフェースを実装する必要がありました。同じシグネチャで特定のメソッド呼び出しのラッパーを作成するだけです。

BiPredicate<List<Integer>,Integer> listContains = new BiPredicate<>() { 
    @Override 
    public boolean test(List<Integer> list, Integer num) { 
     return list.contains(num); 
    } 
}; 

Java 8では、メソッドの参照が追加されました。これにより、このパターンでは構文が大幅に短縮され、より効率的なバイトコードが可能になりました。メソッド参照では、インタフェースの型引数と同じシグネチャを持つメソッドまたはコンストラクタを指定できます。クラス・タイプを使用してメソッド参照を作成すると、クラス・タイプが、使用されている機能インターフェースの第1汎用引数として割り当てられます。これは、そのジェネリック型を使用するパラメータがクラスのインスタンスである必要があることを意味します。

インスタンスメソッドが通常どんなパラメータも取らない場合でも、インスタンスをパラメータとしてとるメソッド参照を引き続き使用できます。例:

Predicate<String> pred = String::isEmpty; 
pred.test(""); // true 

詳細については、Java Tutorial for Method Referencesを参照してください。

+0

ありがとうございます。これは私にとってより明確になります。最初の引数は、参照されたメソッドが呼び出されたオブジェクトです。 2番目、3番目、...引数は、参照されるメソッドのパラメータです。これは、私の元のポストのコードがそれと同じように機能する理由を説明します。 – Ali

+2

申し訳ありませんが、私は答えにしばらく時間がかかりました。私は車に乗っていて、少し車が病気になっていました。 – 4castle

+0

注意しないでください!これらの投稿は待つことができます! – Ali

関連する問題