2017-07-20 22 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#,但在我看来,这是一个奇怪的选择。 –