Java 8 BiPredicate在第一个参数上自动调用方法?

时间:2017-02-15 16:55:27

标签: java java-8 method-reference

我有以下代码:

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)中,方法&#34;包含&#34;是在第一个参数上调用,第二个参数作为参数传入?相当于:

的东西
System.out.println(aList.contains(20));

换句话说,如何将语句listContains.test(aList,20)转换为aList.contains(20)?

这是java 8 BiPredicate的工作原理吗?有人可以解释魔法是如何发生的(有一些参考文献)吗?

这不是重复的帖子。这不同于&#34;“特定类型的任意对象”在java 8中是什么意思?&#34;因为它没有显式传递方法参考。很明显如何在您引用的帖子中传递方法引用。调用该方法的数组实例作为参数传递给Arrays.sort()。就我而言,方法&#34;包含&#34;在aList上被调用是不明显的。我正在寻找关于其工作原理的参考或解释。

似乎有些人更喜欢投票而不是提供参考或解释。他们给人的印象是他们有知识但拒绝分享。

1 个答案:

答案 0 :(得分: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