Saturday 27 August 2016

Java 8 Method references and Lambda expression

Background

In couple of previous posts we saw use of Lambda expressions - 
 In this post we will see method references, a new feature introduced in Java 8. This is again closely related to Lambda expression. So before you proceed with this post kindly revise above posts on Lambda expressions and make sure you are comfortable using those.

Java 8 Method references

There are 4 types of method references - 
  1. Reference to a static method
  2. Reference to a constructor
  3. Reference to an instance method of an arbitrary object of a particular type
  4. Reference to an instance method of a particular object

Details in diagram below -


 Reference to a static method

Consider following example -

        List<String> employeeNameList = Arrays.asList("Aniket", "Payas","Sudhir","Shivam","Anuj");
        Consumer<List<String>> methodRef1 = Collections::sort;
        methodRef1.accept(employeeNameList);
        System.out.println(employeeNameList);


Output of which is : [Aniket, Anuj, Payas, Shivam, Sudhir]

As you can see we have used reference to static method sort  of class Collections. Here we have used Consumer functional interface that takes a single argument and return type is void.

Lambda analog :

Consumer<List<String>> lambdaRef1 = l -> Collections.sort(l); 


Reference to a constructor

Consider following example - 

        Supplier<ArrayList<String>> methodRef2 = ArrayList::new;
        List<String> newEmployeeNameList = methodRef2.get();
        newEmployeeNameList.add("Aniket");
        newEmployeeNameList.add("Abhijit");
        System.out.println(newEmployeeNameList);

Output of which is : [Aniket, Abhijit]

Here we have used Supplier functional interface whose job is to return a given object type (it does not take any argument). In this case it returns our new ArrayList object.

Lambda analog :

Supplier<ArrayList> lambdaRef2 = () -> new ArrayList();

Reference to an instance method of an arbitrary object of a particular type

Consider following example -

        Predicate<String> methodRef3 = String::isEmpty;
        String emtptyString = "";
        System.out.println(methodRef3.test(emtptyString));


Output of which is : true

Here we have used a Predicate  functional interface that take single argument of a type and returns boolean. This may look similar to static method reference but it is not. isEmpty() is not a static but an instance method in String class.

Lambda analog :

Predicate<String> lambdaRef3 = s -> s.isEmpty(); 


Reference to an instance method of a particular object

Consider following example -

        String myName = "Aniket";
        Predicate<String> methodRef4 = myName::contains;
        System.out.println(methodRef4.test("ike"));


Output of which is : true

Here again we have used Predicate functional interface but notice how here we are using reference of a method in a particular instance rather than a class.

Lambda analog :

Predicate<String> lambda2 = s -> str.contains(s);


NOTE : One thing that is commonn to all method references is deferred execution just like Lambdas. They are just references ready to be executed at a later point in runtime.

NOTE (Common functional interfaces):
  • Predicate : Takes a single paramter of any type and returns a boolean - boolean test(T t)
  • Consumer : Takes a single paramter of any type and has a void return type - void accept(T t)
  • Supplier : Does not take any paramter and returns any type  - T get()
  • UnaryOperator : Takes a single paramter of any type and returns of same type. - R apply(T t)



Related Links

t> UA-39527780-1 back to top