2017-07-20 21 views

回答

6

String::startWithstartWith()方法應用於lambda的第一個參數。

""::startWith施加startWith()方法所涉及的""字面或到未聲明爲的λ參數的變量的更廣泛的方式。

爲了更詳盡,提供方法參考的這兩種方法是不可替代的。

假設您想對public boolean startsWith(String prefix)方法使用方法參考。
我將其指定爲方法過載。

使用的λ參數的方法,參考被設計而使用的λ參數未聲明的變量的方法參考設計有Predicate<String>功能接口工作,並具一個BiPredicate<String, String>功能接口工作。

  • 與作爲該方法引用的目標通過一個可變的方式:

    String myVariable; myVariable::startWith

已經提供應在其上應用該方法的參考字符串。這裏:myVariable
所以,只有前綴參數需要在lambda中傳遞。
因此Predicate<String>西裝。

  • 使用拉姆達參數的第一個參數作爲該方法引用的目標的方式:

    String::startsWith

不提供字符串在其上的方法應該參考應用。
所以,方法應該被調用的字符串和前綴參數都需要在lambda中傳遞。
因此BiPredicate<String, String>適合。

下面是一個示例代碼來說明:

public static void main(String[] args) { 

    // using method reference with lambda parameter 
    myMethodWithBiPredicate((s, prefix) -> s.startsWith(prefix), "mystring", "my"); 
    myMethodWithBiPredicate(String::startsWith, "mystring", "my"); 

    // using method reference with variable not in lambda parameter 
    String stringNotInLambdaParams = "stringNotInParam"; 
    Predicate<String> functionPredicate = stringNotInLambdaParams::startsWith; 

    System.out.print("myMethodWithBiPredicate with string " 
      + "(included in the method reference)=" 
      + stringNotInLambdaParams 
      + " and prefix= string | Result = "); 

    myMethodWithPredicate(functionPredicate, "string"); 

} 

public static void myMethodWithBiPredicate(BiPredicate<String, String> function, 
     String string, 
     String prefix) { 

    System.out.println("myMethodWithBiPredicate with string=" 
      + string + " and prefix= " + prefix 
      + " | Result = " + function.test(string, prefix)); 
} 

public static void myMethodWithPredicate(Predicate<String> function, String prefix) { 
    System.out.println(function.test(prefix)); 
} 

產生以下輸出:

myMethodWithBiPredicate與字符串= MyString中和前綴=我的|結果 = true

myMethodWithBiPredicate with string = mystring and prefix = my |結果 = true

myMethodWithPredicate with string(包含在方法 參考中)= stringNotInParam和prefix = string |結果= true

+0

設計師使用該語法有多麼奇怪。無論如何感謝解釋。 –

+4

@Aluan Haddad:我在這裏看不到任何混亂。 'object :: method'將在'object'上調用'method'。 'Class :: method'沒有對象,因此,如果'method'不是'static',目標對象就成爲第一個函數參數。換句話說,'String :: startsWith'等價於'(a,b) - > a.startsWith(b)'和'「」:: startsWith'等價於'b - >「」.startsWith(b) '(相當於'b - > b.isEmpty()') – Holger

+0

我對此感到困惑的是,使用'::'來解析靜態和實例成員,在兩種情況下都避開'.'。從C++的角度來看,'::'會解析一個靜態成員,'.'會解析一個實例成員。從C#POV中,'.'也可以解決。當然,我們不是在談論C++或C#,但在我看來,這是一個奇怪的選擇。 –