What are Method references in java 8

You are here : Home / Core Java Tutorials / Java 8 tutorial

1) What are Method references in java 8?
We use Lambda expressions to replace anonymous methods in java 8.

But at times, a lambda expression does nothing but call an existing method.
In such cases, it's better to refer to the existing method by name.
Method references enables us to do that.

Method references are easy-to-read lambda expressions for methods that already have a name.


2) Advantage of using Method references in java 8 >

  • Method references make code easy to read, and more clean in java 8.
  • We can group all relevant code in a static method, and create a reference to that static method instead.
  • So, we can avoid using bulky anonymous inner class or even lambda expression.


3) What are Method references?
.
There are 4 types of Method reference in Java 8 >
  1. reference to static method  -
ContainingClass::staticMethodName
  1. Reference to an instance method of a particular object -
containingObject::instanceMethodName
  1. Reference to an instance method of an arbitrary object of a particular type -
ContainingType::methodName
  1. Reference to a constructor -
ClassName::new


4) reference to static method in java 8

4.1) Program - Find sum of two numbers using > reference to static method
Here MyInteger::sum is a reference to static method sum of class MyInteger

//Example - Reference to a static method in java 8

@FunctionalInterface
interface CalculatorInterface<A, B> {
   A sumMethod(B val1, B val2);
}
class MyInteger {
   static int sum(Integer i1, Integer i2) {
          return (i1 + i2);
   }
}
public class LambdaExpression_FunctionalInterface_calculatorSum__ReferenceToStaticMethod {
   public static void main(String[] args) {
       // Provide implementation (definition) of sumMethod in java 8
       System.out.println("1 - Find sum of two numbers using > reference to static method ");
       System.out.println("2 - Here MyInteger::sum is a reference to "
                                            + "> static method sum"
                                            + "> of class MyInteger");
        CalculatorInterface<Integer, Integer> sum = MyInteger::sum;
         // Call sumMethod
         Integer sumResult = sum.sumMethod(2, 3);
         System.out.println("sumResult = " + sumResult); // 5
   }
}
/* OUTPUT
1 - Find sum of two numbers using > static method reference,
2 - Here MyInteger::sum is a reference to > static method sum> of class MyInteger
sumResult = 5
*/

But, how call to method sum is resolved in java 8?
The JRE infers the method type arguments, which in this case are (Integer, Integer)


See equivalent lambda expression of above to find sum of two numbers >

CalculatorInterface<Integer, Integer> sum = (a, b) -> (a + b) ;


4.2) Program - Sort String array using > reference to static method
Here StringArraySort::sortMethod is a reference to static method sortMethod of class StringArraySort

//Example - Reference to a static method in java 8

import java.util.Arrays;
class StringArraySort {
   public static int sortMethod(String a, String b) {
          return a.compareTo(b);
   }
}
public class SortStringArrayLambdaExpressionExample1 {
   public static void main(String... args) {
          String[] stringArray = { "ab", "ef", "cd" };
          System.out.println("1 - Sort StringArray using > reference to static method ");
          System.out.println("2 - Here StringArraySort::sortMethod is a reference to "
                       + "> static method sortMethod"
                       + "> of class StringArraySort");
          Arrays.sort(stringArray, StringArraySort::sortMethod);
          System.out.print("Display sorted StringArray > ");
          for (String str : stringArray) {
                 System.out.print(str + " ");
          }
   }
}
/* Output
1 - Sort StringArray using > reference to static method
2 - Here StringArraySort::sortMethod is a reference to > static method sortMethod> of class StringArraySort
Display sorted StringArray > ab cd ef
*/

See equivalent lambda expression in java 8 of above to sort String array >




4.3) Program - convert String To Integer using reference to an static method
Here Integer::valueOf is a reference to static method valueOf of class String

//convert String To Integer using reference to an static method in java 8
@FunctionalInterface
interface MyInterface<A, B> {
   A convertStringToIntegerMethod(B stringVal);
}
public class LambdaExpression_ReferenceToStaticMethod {
   public static void main(String[] args) {
          // The method reference Integer::valueOf is a reference to a static method
          MyInterface<Integer, String> integerVal = Integer::valueOf;
          // Call convertStringToInteger
          Integer result = integerVal.convertStringToIntegerMethod("12");
          System.out.println(result); // 12
   }
}
/* OUTPUT
Integer = 12
*/



5) Reference to an instance method of a particular object in java 8 -

5.1) Program - Find sum of two numbers using > Reference to an instance method of a particular object
Here myInteger::sum  is a reference to instance method sum of object myInteger

//Example - reference to an instance method of a particular object in java 8.
@FunctionalInterface
interface CalculatorInterface<A, B> {
   A sumMethod(B val1, B val2);
}
class MyInteger {
   int sum(Integer i1, Integer i2) {
          return (i1 + i2);
   }
}
public class LambdaExpression_FunctionalInterface_calculatorSum__ReferenceToInstanceMethod {
   public static void main(String[] args) {
         
          System.out.println("1 - Find sum of two numbers using > "
                       + "Reference to an instance method of a particular object");
          MyInteger myInteger = new MyInteger();
            System.out.println("2 - The myInteger::sum  is a reference to "+
                       "instance method sum "
                       + "of object myInteger");
          CalculatorInterface<Integer, Integer> sum = myInteger::sum;
          // Call sumMethod
          Integer sumResult = sum.sumMethod(2, 3);
          System.out.println("sumResult = " + sumResult); // 5
   }
}
/* OUTPUT
1 - Find sum of two numbers using > Reference to an instance method of a particular object
2 - The myInteger::sum  is a reference to instance method sum of object myInteger
sumResult = 5

*/





5.2) Program - Sort String array using > Reference to an instance method of a particular object
Here String::stringSortMethod  is a reference to instance method stringSortMethod of object StringSort

//Example - reference to an instance method of a particular object in java 8.
 
import java.util.Arrays;
class StringSort {
   public int stringSortMethod(String a, String b) {
          return a.compareTo(b);
   }
}
public class SortStringArrayLambdaExpressionExample2 {
   public static void main(String... args) {
          String[] stringArray = { "ab", "ef", "cd" };
          System.out.println("1- Sort StringArray using > "
                       + "Reference to an instance method of a particular object");
          StringSort myStringSort = new StringSort();

          System.out.println("2 - Here String::stringSortMethod is a reference to "
                       + "> instance method StringSort "
                       + "> of class String");
          Arrays.sort(stringArray, myStringSort::stringSortMethod);
          System.out.print("Display sorted StringArray > ");
          for (String str : stringArray) {
                 System.out.print(str + " ");
          }
   }
}
/* Output
1- Sort StringArray using > Reference to an instance method of a particular object
2 - Here String::stringSortMethod is a reference to > instance method StringSort > of class String
Display sorted StringArray > ab cd ef
*/



6) Reference to an instance method of an arbitrary object of a particular type in java 8

Program to sort String array  - using - Reference to an instance method of an arbitrary object of a particular type
//Example- Reference to an instance method of an arbitrary object of a particular type in java 8
import java.util.Arrays;
public class ReferenceToInstanceMethodOfArbitraryObjectOfParticularType {
   public static void main(String... args) {
     
       //Reference to an instance method of an arbitrary object of a particular type
       System.out.println("1 - Reference to an instance method of an arbitrary object of a particular type");
       System.out.println("2 - Here String::compareToIgnoreCase is a reference to "
                       + "> instance method compareToIgnoreCase "
                       + "> of class String");
         
       String[] stringArray = { "ab", "Ef", "cd" };
       Arrays.sort(stringArray, String::compareToIgnoreCase);
       System.out.print("Display sorted StringArray > ");
       for (String str : stringArray) {
             System.out.print(str + " ");
       }   
   }
}
/* Output
1 - Reference to an instance method of an arbitrary object of a particular type
2 - Here String::compareToIgnoreCase is a reference to > instance method compareToIgnoreCase > of class String
Display sorted StringArray > ab cd Ef
*/

See equivalent lambda expression of above to sort String array >





7) Reference to a constructor

Constructor reference is used widely in java 8. Let’s see step to create and access it >
  1. Constructor reference -
Create reference to the Employee constructor by using Employee::new
  1. Call createEmployee method
When EmployeeFactory.createEmployee method is called it automatically selects the constructor by matching the arguments type
  1. In this example it will select constructor Employee constructor - One Argument (i.e. String argument)

Program - Constructor reference
//Example - Constructor reference

//Create Employee class
class Employee {
   String firstName;
   Employee() {
      System.out.println("Employee constructor - No Argument");
   }
   Employee(String firstName) {
      System.out.println("3 - Employee constructor - One Argument (i.e. String argument)");
       this.firstName = firstName;
   }
  
   public String getName(){
      return firstName;
   }
}
//Create EmployeeGenerator Interface
@FunctionalInterface
interface EmployeeGenerator{
  //createEmployee method returns Employee type object
  abstract Employee createEmployee(String firstName);
}
//Instead of implementing the factory manually, we glue everything together via constructor references:
public class ConstructorReferenceUsingEmployeeClass{
   public static void main(String[] args) {
         
          System.out.println("1 - Constructor reference");
          System.out.println("Create reference to the Employee constructor by using Employee::new");
          EmployeeGenerator empFactory = Employee::new;
          //NOTE: The target type of this Employee::new must be a functional interface only (Example > Employee::new can be assigned to some functional interface)
         
          System.out.println("2 - Call createEmployee method");
          System.out.println("When EmployeeFactory.createEmployee method is called "
                  + "it automatically selects the constructor by matching the arguments type");
          //Example - In this case it will select constructor with One Argument (i.e. with String argument)
          Employee emp = empFactory.createEmployee("Ankit");
          System.out.println("4 - emp.getName() > "+emp.getName());
   }
}
/*OUTPUT
1 - Constructor reference
Create reference to the Employee constructor by using Employee::new
2 - Call createEmployee method
When EmployeeFactory.createEmployee method is called it automatically selects the constructor by matching the arguments type
3 - Employee constructor - One Argument (i.e. String argument)
4 - emp.getName() > Ankit
*/

Important NOTE: The target type of this Employee::new must be a functional interface only (Example > Employee::new can be assigned to some functional interface (like EmployeeGenerator) )

Labels: Java 8
Must read for you :