Java Method Reference Types and Examples

Filed Under: Java
Java Method Reference

Java Method Reference was introduced in Java 8, along with lambda expressions. The method reference is a shortcut way to create lambda expressions when it just calls a method.

What is Java Method Reference?

The method reference allows us to create a lambda expression from an existing method. It’s used when the lambda expression is calling a function and doing nothing else. The JVM takes care of creating the lambda expression by mapping the input variables to the method arguments.

Method Reference Syntax

The method reference has two parts – class/object and method/constructor. They are separated by double colons (::). There are no additional parameters passed with the method reference.

Types of Method References

There are four types of method references in Java.

  1. Static Method Reference: its syntax is Class::StaticMethodName
  2. Reference to an Object instance method: the syntax is Object::instanceMethodName
  3. Reference to an instance method of an arbitrary object of specific type: the syntax is Class::instanceMethodName
  4. Constructor Reference: its syntax is ClassName::new
Java Method Reference Types

Java Method Reference Types

Java Method Reference Examples

Let’s look at the examples of all the four types of method references. We will first create a lambda expression and then use the method reference to have the same effect.

1. Static Method Reference

Let’s say we have a functional interface as below.


@FunctionalInterface
interface Counter {
	int count(Object[] objArray);
}

We have a Utils class to get the number of elements in an array.


class Utils {

	public static int countElements(Object[] array) {
		return array.length;
	}
}

We will use a lambda expression to call the Utils class countElements() method to get the number of elements in an array.


Integer[] intArray = { 1, 2, 3, 4, 5 };

// lambda expression
Counter counter2 = array -> Utils.countElements(array);

System.out.println(counter2.count(intArray)); // 5

Here, the lambda expression is simply calling the Utils class static method and not doing anything else. This is a perfect place to use a method reference to call the static method.


Counter counter = Utils::countElements;

2. Object Instance Method Reference

Let’s change the Utils class implementation and create an instance method.


class Utils {

	public int count(Object[] array) {
		return array.length;
	}
}

Now, we will create a lambda expression calling this instance method.


Utils ut = new Utils();
		
Counter counter1 = array -> ut.count(array);

We can replace the lambda expression with instance method reference.


Counter counter1 = ut::count;

We can instantiate the Utils class in the method reference itself.


Counter counter1 = new Utils()::count;

3. Reference to the instance method of an arbitrary object

Sometimes, we call a method of an argument in the lambda expression. In that case, we can use a method reference to call an instance method of an arbitrary object of a specific type.

Let’s say we have a lambda expression like this.


String[] strArray = { "A", "E", "I", "O", "U", "a", "e", "i", "o", "u" };

Arrays.sort(strArray, (s1, s2) -> s1.compareToIgnoreCase(s2));

Here, the lambda expression is simply calling a method. So, we can use method reference here. But, the method is called on an arbitrary object of String. So, we can call the instance method by referring to the String class.


Arrays.sort(strArray, String::compareToIgnoreCase);

4. Constructor Method Reference

The Stream collect() method accepts a Supplier argument. The supplier should return a new instance every time. So, the lambda expression must call the constructor. Let’s look at a simple example.


List<Integer> intList = List.of(1, 2, 3, 4, 5);

String concat1 = intList.parallelStream().collect(
		() -> new StringBuilder(),
		(x, y) -> x.append(y),
		(a, b) -> a.append(b)).toString();

Here, we can replace “() -> new StringBuilder()” to a constructor method reference.


String concat1 = intList.parallelStream().collect(
		StringBuilder::new,
		(x, y) -> x.append(y),
		(a, b) -> a.append(b)).toString();

Well, we don’t have to stop here. The other two lambda expressions can also be replaced by a method reference.


String concat1 = intList.parallelStream().collect(
		StringBuilder::new,
		StringBuilder::append,
		StringBuilder::append).toString();

Reference

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages