Java Method Reference.
Java Method Reference
- A method reference is shorthand to create a lambda expression using an existing method.
- Using method references makes your lambda expressions more readable and concise.
- If a lambda expression contains a body that is an expression using a method call, you can use a method reference in place of that lambda expression.
- For instance you want to print the event object whenever a button is clicked – you could of course with lambda write:
button.setOnAction(event -> System.out.println(event));
- It would be nicer if you could just pass the println method to the setOnAction method:
button.setOnAction(System.out::println);
- The expression System.out::println is a method reference that is equivalent to the lambda expression x -> System.out.println(x).
- The :: operator separates the method name from the name of an object or class.
- Types of Method References:
Syntax Description TypeName::staticMethod A method reference to a static method of a class, an interface, or an enum objectRef::instanceMethod A method reference to an instance method of the specified object ClassName::instanceMethod A method reference to an instance method of an arbitrary object of the specified class TypeName.super::instanceMethod A method reference to an instance method of the supertype of a particular object ClassName::new A constructor reference to the constructor of the specified class ArrayTypeName::new An array constructor reference to the constructor of the specified array type
TypeName::staticMethod
- In this case we need a static method that can be executed through the class name :
public class Calculator { // static method and owned bye the class public static int mul(int a, int b) { return a * b; } public static void main(String[] args) { // Using a lambda expression IntBinaryOperator operator1 = (a, b) -> Calculator.mul(a, b); System.out.println(operator1.applyAsInt(5, 6)); // Using a method reference IntBinaryOperator operator2 = Calculator::mul; System.out.println(operator2.applyAsInt(5, 6)); } }
The result of this is:30 30
objectRef::instanceMethod and ClassName::instanceMethod
- The object reference on which an instance method is invoked is known as the receiver of the method invocation.
- You can specify the receiver of the method invocation: provide it implicitly when the method is invoked.
- Explicitly, which is known as a bound receiver.
- provide it implicitly when the method is invoked, which is known as unbound receiver
Bound receiver
For a bound receiver, use the objectRef::instanceMethod syntax.public class BoundType { // instance method public int cubic(int a) { return a * a * a; } public static void main(String[] args) { BoundType cal = new BoundType(); // Using a lambda expression Function<Integer, Integer> operator3 = (a) -> cal.cubic(a); System.out.println(operator3.apply(6)); // Using a method reference (bound type) Function<Integer, Integer> operator4 = cal::cubic; System.out.println(operator4.apply(6)); } }
The result of this is:216 216
UnBound receiver
For an unbound receiver, use the ClassName::instanceMethod syntax.public class UnBoundType { // instance method public int cubic(int a) { return a * a * a; } public static void main(String[] args) { UnBoundType cal = new UnBoundType(); // Using a lambda expression BiFunction<UnBoundType, Integer, Integer> operator1 = (a, b) -> a.cubic(b); System.out.println(operator1.apply(cal, 6)); // Using a method reference (UnBound type) BiFunction<UnBoundType, Integer, Integer> operator2 = UnBoundType::cubic; System.out.println(operator2.apply(cal, 6)); } }
The result of this is:216 216
TypeName.super::instanceMethod
- The keyword super is used as a qualifier to invoke the overridden method in a class or an interface.
-
The keyword is available only in an instance context.
interface Defaults { default int doMath(int a) { return 2 * a; } } public class Calculator implements Defaults { // static method and owned bye the class @Override public int doMath(int a) { return a * a; } public void test(int value) { // Uses Calculator.doMath() method Function<Integer, Integer> operator1 = this::doMath; System.out.println("this::doMath(): " +operator1.apply(value)); // Uses Defaults.doMath() method Function<Integer, Integer> operator2 = Defaults.super::doMath; System.out.println("Defaults::doMath(): " +operator2.apply(value)); } public static void main(String[] args) { Calculator cal = new Calculator(); cal.test(7); } }
The result of this is:this::doMath(): 49 Defaults::doMath(): 14
ClassName::new
- Constructor references are just like method references, except that the name of the method is new.
- For example, Button::new is a reference to a Button constructor.
- The context determines which button constructors to be used as there are several such to choose between.
List<String> labels = ...; Stream<Button> stream = labels.stream().map(Button::new); List<Button> buttons = stream.collect(Collectors.toList());
- The compiler picks the one with a String parameter because it infers from the context that the constructor is called with a string.
-
You can form constructor references with array types.
int[] :: new; // the parameter is length of the array. x -> new int[x]; // This is the equivalent lambda expression
-
Here is two constructor references example:
public class Timer { public void oper(Supplier<GregorianCalendar> supplier) { System.out.println(supplier.get().getTime()); } public static void main(String[] args) { Timer timer = new Timer(); // Referencing the constructor // Using a lambda expression timer.oper(() -> new GregorianCalendar()); // Using a constructor reference timer.oper(GregorianCalendar::new); } }
interface ArrayCreator { int[] MakeArray(int noOfEle); } public class ArrayNew { public static void main(String[] args) { ArrayCreator arrayCreator = int[]::new; int[] intArr = arrayCreator.MakeArray(10); for (int i = 0; i < intArr.length; i++) { intArr[i] = i * i - i / 2; System.out.println("[" + i + "] = " + intArr[i]); } } }
The result of this is:
andWed Apr 27 11:29:09 CEST 2016 Wed Apr 27 11:29:09 CEST 2016
[0] = 0 [1] = 1 [2] = 3 [3] = 8 [4] = 14 [5] = 23 [6] = 33 [7] = 46 [8] = 60 [9] = 77
© 2010 by Finnesand Data.
All rights reserved.
This site aims to provide FREE programming training and technics.
Finnesand Data as site owner gives no warranty for the
correctness in the pages or source codes.
The risk of using this web-site pages or any program
codes from this website is entirely at the individual user.