Sunday, August 23, 2015

Method References in Java8


Method References:
  • Method references refers to methods or constructors without invoking them.
  • We can use lambda expressions to create anonymous methods. 
  • Sometimes, however, a lambda expression does nothing but call an existing method
  • In those cases, it's often clearer to refer to the existing method by name.
  • Using Method references refer to the existing method by name, they are compact, easy-to-read lambda expressions for methods that already have a name.
  • In java, method references can be specified by using double colon (::) operator.
  • Method reference can be expressed using the lambda expression syntax (->) in order to make it simple :: operator can be used.
Syntax:
           <class_name or instance_name>::<method_name>
Example:
/**
 * @author Ranga Reddy
 * @version 1.0
 */
public class MethodReferenceExample {
    public static void main(String[] args) {
        
        // with out using method reference
        new Thread(
                () -> {System.out.println("Hello, Mr. Ranga"); }
        ) {
            
        }.run();;
        
        // with using method reference
        new Thread(MethodReferenceExample:: sayHello) {
            
        }.run();
        
    }
    
    public static void sayHello() {
        System.out.println("Hello, Mr. Ranga");
    }
}
Types of Method References:
There are four types of method references:

Method Reference Type
Syntax
Example
Reference to a static method
ClassName::staticMethodName
String::valueOf
Reference to a bound non-static method
ObjectName::instanceMethodName
s::toString
Reference to an instance method of an arbitrary object of a particular type
ClassName::instanceMethodName
Object::toString
Reference to a constructor
ClassName::new
String::new
Reference to a static method:
We can call static method references by using ContainingClass::staticMethodName
Example:
public class MethodReferenceExample {
    public static void main(String[] args) {        
        // Reference to a Static Method     
        new Thread(MethodReferenceExample::sayHello).start();
    }       
    public static void sayHello() {     
        System.out.println("Hello, Mr. Ranga");
    }
}
Reference to a bound non-static method:
We can call non-static method using ObjectName:: instanceMethodName
Example:

public class MethodReferenceExample {
    public static void main(String[] args) {
        // Reference to an Instance Method of a Particular Object
        String name = "My name is Ranga Reddy";
        printName(name::toString);      
    }
    
    private static void printName(Supplier<String> supplier) {
        System.out.println(supplier.get());
    }
}
Reference to an instance method of an arbitrary object of a particular type:
We can call non-static method using ClassName:: instanceMethodName

Example:
public class MethodReferenceExample {
    public static void main(String[] args) {
        // Reference to an Instance Method of an Arbitrary Object of a Particular Type
        String[] names = { "Ranga", "Reddy", "Vinod", "Raja", "Manu", "Teja", "Vasu" };     
        Arrays.sort(names, String::compareToIgnoreCase);
        System.out.println(Arrays.toString(names));     
    }
}
Reference to a bound non-static method:
We can call non-static method using ClassName:: new
Example:
@FunctionalInterface
interface EmployeeFactory {
    Employee getEmployee(long id, String name, Integer age);
}

class Employee {
    private long id;
    private String name;
    private int age;
        
    public Employee() {     
        this(1, "Ranga", 27);
    }
    
    public Employee(long id, String name, int age) {
        super();
        this.id = id;
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Employee [id=" + id + ", name=" + name + ", age=" + age + "]";
    }   
}

public class MethodReferenceExample {
    public static void main(String[] args) {                
        // Reference to constructor
        EmployeeFactory employeeFactory = Employee :: new;
        Employee employee = employeeFactory.getEmployee(1, "Ranga Reddy",27);
        System.out.println(employee);       
    }
}
When to use method references:
When a lambda expression is invoking already defined method, then we can replace it with reference to that method.
When we can't use method references:
We can't pass arguments to the method references. So that places we can't use method references.
References:
  1. https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
  2. http://java8.in/java-8-method-references/
  3. http://www.informit.com/articles/article.aspx?p=2191424

0 comments: