Skip to content
Related Articles

Related Articles

Method References in Java with examples
  • Difficulty Level : Medium
  • Last Updated : 02 Mar, 2021

Prerequisites: Functional Interfaces in Java, Lambda Function

A method is a collection of statements that perform some specific task and return the result to the caller. A method can perform some specific task without returning anything. Methods allow us to reuse the code without retyping the code. In this article, we will see how to use methods as value. 

In Java8 we can use the method as if they were objects or primitive values, and we can treat them as a variable. The example shows the function as a variable in java:

// This square function is a variable getSquare. 
Function<Integer, Integer> getSquare = i -> i * i; 
// Pass function as a argument to other function easily 
SomeFunction(a, b, getSquare); 

Sometimes, a lambda expression only calls an existing method. In those cases, it looks clear to refer to the existing method by name. The method references can do this, they are compact, easy-to-read as compared to lambda expression. A method reference is the shorthand syntax for a lambda expression that contains just one method call. Here’s the general syntax of a method reference: 



// To refer a method in an object 
Object :: methodName 

Following is the example of a lambda expression that just calls a single method in its entire execution: 

// To print all element in a list 
list.forEach(s -> System.out.println(s)); 

To make the code clear and compact, In the above example, one can turn lambda expression into a method reference:

// Shorthand to print all element in a list 
list.forEach(System.out::println); 
 

The method references can only be used to replace a single method of the lambda expression. A code is more clear and short if one uses a lambda expression rather than using an anonymous class and one can use method reference rather than using a single function lambda expression to achieve the same. In general, one doesn’t have to pass arguments to method references.

The following example is about performing some operation on elements in the list and add them. The operation to be performed on elements is a function argument and the caller can pass accordingly. 

Java






public int tranformAndAdd(List<Integer> l,
                          Function<Integer, Integer> ops)
{
    int result = 0;
    for (Integer s : l)
        result += f.apply(s);
    return results;
}
 
// Operations utility class
class OpsUtil {
 
    // Function for half the variable
    public static Integer doHalf(Integer x)
    {
        return x / 2;
    }
 
    // Square
    public static Integer doSquare(Integer x)
    {
        return x * x;
    }
    ... many more operations...
}

Following are the ways to call the above method

Java




List<Integer> list = new ArrayLis<>();
// Add some element to list
...
    // Using an anonymous class
    tranformAndAdd(list, new Function<Integer, Integer>() {
        public Integer apply(Integer i)
        {
            // The method
            return OpsUtil.doHalf(i);
        }
    });
 
// Using a lambda expression
tranformAndAdd(list, i -> OpsUtil.doHalf(i));
 
// Using a method reference
tranformAndAdd(list, OpsUtil::doHalf);

There are Four type method reference:

  1. Static Method Reference.
  2. Instance Method Reference of a particular object.
  3. Instance Method Reference of an arbitrary object of a particular type.
  4. Constructor Reference.

To look into all this type we will consider a sorting with comparator example.

 1. Reference to a static method:

If a Lambda expression is like:

// If a lambda expression just call a static method of a class 
(args) -> Class.staticMethod(args)  

Then method reference is like:

// Shorthand if a lambda expression just call a static method of a class 
Class::staticMethod  

Example: 

Java




// This Example shows how one can use
// Static method reference to sort
// with custom comparator
import java.io.*;
import java.util.*;
 
// Object need to be sorted.
class Person {
    private String name;
    private Integer age;
 
    // Constructor
    public Person(String name, int age)
    {
        this.name = name;
        this.age = age;
    }
 
    public Integer getAge() { return age; }
    public String getName() { return name; }
}
 
public class GFG {
 
    // A static method to
    // compare with name
    public static int compareByName(Person a, Person b)
    {
        return a.getName().compareTo(b.getName());
    }
 
    // A static method to
    // compare with age
    public static int compareByAge(Person a, Person b)
    {
        return a.getAge().compareTo(b.getAge());
    }
 
    // Main
    public static void main(String[] args)
    {
        // List of person
        List<Person> personList = new ArrayList<>();
        // Add Elements
        personList.add(new Person("vicky", 24));
        personList.add(new Person("poonam", 25));
        personList.add(new Person("sachin", 19));
 
        // Use static method reference to
        // sort array by name
        Collections.sort(personList, GFG::compareByName);
        System.out.println("Sort by name :");
        personList.stream()
            .map(x -> x.getName())
            .forEach(System.out::println);
 
        // Use static method reference
        // to sort array by age
        Collections.sort(personList, GFG::compareByAge);
        System.out.println("Sort by age :");
        personList.stream()
            .map(x -> x.getName())
            .forEach(System.out::println);
    }
}
Output: 
Sort by name :
poonam
sachin
vicky
Sort by age :
sachin
vicky
poonam

 

2. Reference to an instance method of a particular object: 

If a Lambda expression is like:

// If a lambda expression just call a default method of an object 

(args) -> obj.instanceMethod(args) 

Then method reference is like:

// Shorthand if a lambda expression just call a default method of an object 

obj::instanceMethod 

Example:  

Java




// This Example is same as above but
// using object method reference to
// sort with custom comparator
import java.io.*;
import java.util.*;
 
// Object need to be sorted.
class Person {
    private String name;
    private Integer age;
 
    // Constructor
    public Person(String name, int age)
    {
        this.name = name;
        this.age = age;
    }
 
    public Integer getAge() { return age; }
    public String getName() { return name; }
}
 
// Comparator class
class ComparisonProvider {
    // A method to compare with name
    public int compareByName(Person a, Person b)
    {
        return a.getName().compareTo(b.getName());
    }
 
    // A method to compare with age
    public int compareByAge(Person a, Person b)
    {
        return a.getAge().compareTo(b.getAge());
    }
}
 
public class GFG {
    // Main
    public static void main(String[] args)
    {
        // List of person
        List<Person> personList = new ArrayList<>();
        // Add Elements
        personList.add(new Person("vicky", 24));
        personList.add(new Person("poonam", 25));
        personList.add(new Person("sachin", 19));
 
        // A comparator class with multiple
        // comaparator methods
        ComparisonProvider comparator
            = new ComparisonProvider();
 
        // Use instance method reference
        // to sort array by name
        Collections.sort(personList,
                         comparator::compareByName);
        System.out.println("Sort by name :");
        personList.stream()
            .map(x -> x.getName())
            .forEach(System.out::println);
 
        // Use instance method reference
        // to sort array by age
        Collections.sort(personList,
                         comparator::compareByAge);
        System.out.println("Sort by age :");
        personList.stream()
            .map(x -> x.getName())
            .forEach(System.out::println);
    }
}
Output: 
Sort by name :
poonam
sachin
vicky
Sort by age :
sachin
vicky
poonam

 

3. Reference to an instance method of an arbitrary object of a particular type: 

If a Lambda expression is like:

// If a lambda expression just call an instance method of a  ObjectType 

(obj, args) -> obj.instanceMethod(args) 

Then method reference is like:

// Shorthand if a lambda expression just call an instance method of a ObjectType 

ObjectType::instanceMethod 

Example:  

Java




// This Example shows how one can use
// Instance type method reference
// to sort with custom comparator
 
import java.io.*;
import java.util.*;
 
public class GFG {
    // Main
    public static void main(String[] args)
    {
        // List of person
        List<String> personList = new ArrayList<>();
 
        // Add Elements
        personList.add("vicky");
        personList.add("poonam");
        personList.add("sachin");
 
        // Method reference to String type
        Collections.sort(personList,
                         String::compareToIgnoreCase);
        personList.forEach(System.out::println);
    }
}
Output: 
poonam
sachin
vicky

 

4. Constructor method reference: 

If a Lambda expression is like: 

// If a lambda expression just create an object 
(args) -> new ClassName(args) 

Then method reference is like: 

// Shorthand if a lambda expression just create an object 
ClassName::new 

Example:  

Java




// This Example shows how one
// can use constructor method reference
 
import java.io.*;
import java.nio.charset.Charset;
import java.util.*;
import java.util.function.*;
 
// Object need to be sorted.
class Person {
    private String name;
    private Integer age;
 
    // Constructor
    public Person()
    {
        Random ran = new Random();
 
        // length is bounded by 7
        byte[] array = new byte[7];
        ran.nextBytes(array);
 
        // Asigning Random values
        // to name and age
        this.name
            = ran
                  .ints(97, 122 + 1)
                  .limit(7)
                  .collect(StringBuilder::new,
                           StringBuilder::appendCodePoint,
                           StringBuilder::append)
                  .toString();
        this.age = age;
    }
 
    public Integer getAge()
    {
        return age;
    }
    public String getName()
    {
        return name;
    }
}
 
public class GFG {
 
    // Get List of objects of given
    // length and Supplier
    public static <T> List<T>
    getObjectList(int length,
                  Supplier<T> objectSupply)
    {
        List<T> list = new ArrayList<>();
 
        for (int i = 0; i < length; i++)
            list.add(objectSupply.get());
        return list;
    }
 
    public static void main(String[] args)
    {
 
        // Get 10 person by suppliying
        // person supplier, Supplier is
        // created by person constructor
        // reference
        List<Person> personList
            = getObjectList(5, Person::new);
 
        // Print names of personList
        personList.stream()
            .map(x -> x.getName())
            .forEach(System.out::println);
    }
}
  1.  
Output: 
vzskgmu
iupltfx
kocsipj
lyvhxsp
hbdphyv

 

Conclusion: 

As mentioned above, if a lambda expression only calls an existing method then using method reference can make code more readable and clear. There are many more things we can do with Java8 Lambda and Method References while using Java streams.

Attention reader! Don’t stop learning now. Get hold of all the important Java Foundation and Collections concepts with the Fundamentals of Java and Java Collections Course at a student-friendly price and become industry ready. To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

My Personal Notes arrow_drop_up
Recommended Articles
Page :