0

I have the following code:

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?
    }
}

In the statement listContains.test(aList, 20), how is it that the method "contains" is getting called on the first argument and the second argument is passed in as a parameter? Something equivalent to:

System.out.println(aList.contains(20));

In other words, how does the statement listContains.test(aList, 20) get translated to aList.contains(20)?

Is this how java 8 BiPredicate work? Could someone explain how the magic is happening (with some references)?

This is not a duplicate post. This differs from "What does “an Arbitrary Object of a Particular Type” mean in java 8?" in that its not explicitly passing method reference around. It is very clear how method reference is being passed around in the post you reference. The array instance on which the method is being called is passed as an argument to Arrays.sort(). In my case, how the method "contains" is being called on aList is not apparent. I am looking for a reference or explanation as to how its working.

It seems some individuals prefer to down vote instead of provide reference or explanation. They give the impression that they have knowledge but refuse to share it.

Ali
  • 1,442
  • 1
  • 15
  • 29
  • 3
    It isn't specific to `BiPredicate`. You may want to research how method references work. – 4castle Feb 15 '17 at 16:59
  • @4castle Thanks for the reply. I understand that calling 'test' method on BiPredicate reference 'listContains' will in turn call the List::contains method. But how is the object selected on which it is called (aList in this example)? It is not completely clear in this example. Do you have an example that doesn't use BiPredicate? – Ali Feb 15 '17 at 17:13
  • 1
    I find [this reference](http://moandjiezana.com/blog/2014/understanding-method-references/) useful. Look at the section "Desugaring Lambdas". – Enwired Feb 15 '17 at 17:58

1 Answers1

2

BiPredicate is an interface which has only one method, test.

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

Interfaces which have only one method are called functional interfaces. Previous to Java 8, you would often times have to implement these interfaces using an anonymous class, just to create a wrapper for a certain method call with the same signature. Like this:

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

In Java 8, method references were added, which allowed for a much shorter syntax and more efficient bytecode for this pattern. In a method reference, you can specify a method or constructor which has the same signature as the type arguments for the interface. When you make a method reference using a class type, it assigns the class type as the first generic argument of the functional interface being used. This means whatever parameter which uses that generic type will need to be an instance of the class.

Even if the instance method normally doesn't take any parameters, a method reference can still be used which takes an instance as the parameter. For example:

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

For more information, see the Java Tutorial for Method References.

4castle
  • 32,613
  • 11
  • 69
  • 106
  • Thanks for the explanation. This makes it more clearer for me. The first argument is the object on which the referenced method called. The second, third, ... arguments are the parameters to the referenced method. This explains why the code in my original post work the way it does. – Ali Feb 15 '17 at 18:09
  • 2
    Sorry it took me a while to answer. I was riding in the car and getting a little car sick. – 4castle Feb 15 '17 at 18:15
  • Don't drive distracted! These posts can wait! – Ali Feb 15 '17 at 18:17