2017-02-15 52 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

相关问题