2017-02-15 50 views
0

我有以下代碼: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? 
    } 
} 

在聲明listContains.test(ALIST,20),它是如何的方法「包含」獲取調用的第一個參數和第二個參數傳入作爲參數?東西等同於:

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

我發現[this reference](http://moandjiezana.com/blog/2014/understanding-method-references/)有用。看看「Desugaring Lambdas」一節。 – Enwired

回答

2

BiPredicate是一個接口,它只有一個方法,test

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

只有一種方法的接口稱爲功能接口。在Java 8之前,您經常需要使用匿名類來實現這些接口,只是爲具有相同簽名的特定方法調用創建包裝器。像這樣:

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

在Java 8中,添加了方法引用,這允許使用更短的語法和更高效的此模式的字節碼。在方法引用中,可以指定與接口的類型參數具有相同簽名的方法或構造方法。當您使用類類型進行方法引用時,它會將類類型指定爲正在使用的功能接口的第一個通用參數。這意味着使用該泛型類型的任何參數都需要成爲該類的一個實例。

即使實例方法通常不會接受任何參數,仍然可以使用方法引用,它將實例作爲參數。例如:

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

欲瞭解更多信息,請參閱Java Tutorial for Method References

+0

感謝您的解釋。這使我對它更清晰。第一個參數是所引用的方法調用的對象。第二,第三,......參數是被引用方法的參數。這解釋了爲什麼我原來的文章中的代碼是按照它的方式工作的。 – Ali

+2

對不起,我花了一段時間纔回答。我坐在車裏,弄了一輛車。 – 4castle

+0

不要開車分心!這些帖子可以等待! – Ali

相關問題