There are 3 categories of lambda expression that we could convert to method references.
All of these consist of a single method invocation.
1) Invoking an instance method on the first argument of the lambda
2) Invoking a static method on the first argument of the lambda
3) Invoking an instance method on a variable that doesn’t make part of the lambda arguments.
The 1) and 2) ways use the same syntax : className::methodName.
While the 3) way uses the syntax : variable::methodName.
Examples of each one of them
1) Invoking an instance method on the first argument of the lambda
Suppose a BiConsumer lambda that takes as parameter a List of String and a String.
BiConsumer<List<String>, String> addInListConsumer = (list, s) -> list.add(s); addInListConsumer = List::add; // method reference way |
2) Invoking a static method
Suppose a Function lambda that takes as parameter an array of String and returns a List of String.
Function<String[], List<String>> toListFunction = (array) -> Arrays.asList(array); toListFunction = Arrays::asList;// method reference way |
3) Invoking an instance method on a variable that doesn’t make part of the of the lambda arguments.
Suppose a Function lambda that takes as parameter two indexes (start and end) and return a String variable that doesn’t make part of the lambda parameters.
String myString = "!hello"; BiFunction<Integer, Integer, String> substringFunction = (start, end) -> myString.substring(start, end); substringFunction = myString::substring;// method reference way |
All these examples show that method references rely strongly on inference type, order of the lambda parameters and type matching.
Method reference feature is really a very short way to define the implementation of a functional interface.
Arguments of lambdas are generally written twice : in the lambda parameters and in the body of the lambda.
With method references, these are specified nowhere.
At the beginning, using method references may be disconcerting as the target and the parameters of the method invoked are not always explicit.
But after a some time, using it becomes really intuitive.