Overview
In this tutorial, we will learn Java 8 method references with examples.
Java provides a new feature called method reference in Java 8. Method reference is used to refer method of the functional interface. It is a compact and easy form of a lambda expression. Each time when you are using a lambda expression to just referring a method, you can replace your lambda expression with a method reference.
In this post, we will learn what is method reference, what are their benefits, and what are different types of method references.
Kinds of Method References
1. Reference to a static method
Example:
ContainingClass::staticMethodName
2. Reference to an instance method of a particular object
Example:
containingObject::instanceMethodName
3. Reference to an instance method of an arbitrary object of a particular type
Example:
ContainingType::methodName
4. Reference to a constructor
Example:
ClassName::new
Let's discuss these method references one by one with examples.
1. Reference to a Static Method
You can refer to the static method defined in the class. Following is the syntax and example which describe the process of referring to static method in Java.
Syntax :
Syntax :
ContainingClass::staticMethodName
Example 1: This example shows, how the lambda expression replaced with method refers to the static method.
package com.java.lambda; import java.util.*; import java.util.function.BiFunction; import java.util.function.Function; public class MethodRefDemo { public static int addition(int a, int b){ return (a + b); } public static void main(String[] args) { // 2. Method reference to a static method of a class Function<Integer, Double> sqrt = (Integer input) -> Math.sqrt(input); System.out.println(sqrt.apply(4)); Function<Integer, Double> sqrtRef = Math::sqrt; System.out.println(sqrtRef.apply(4)); BiFunction<Integer, Integer, Integer> functionLambda = (a, b) -> MethodRefDemo.addition(a, b); System.out.println(functionLambda.apply(10, 20)); BiFunction<Integer, Integer, Integer> function = MethodRefDemo::addition; System.out.println(function.apply(10, 20)); } }
Example 2: we can also override static methods by referring to methods. In the following example, we have defined and overloaded three add methods.
import java.util.function.BiFunction;
class Arithmetic {
public static int add(int a, int b) {
return a + b;
}
public static float add(int a, float b) {
return a + b;
}
public static float add(float a, float b) {
return a + b;
}
}
public class ReferenceToStaticMethod2 {
public static void main(String[] args) {
BiFunction<Integer, Integer, Integer> adder1 = Arithmetic::add;
BiFunction<Integer, Float, Float> adder2 = Arithmetic::add;
BiFunction<Float, Float, Float> adder3 = Arithmetic::add;
int result1 = adder1.apply(10, 20);
float result2 = adder2.apply(10, 20.0f);
float result3 = adder3.apply(10.0f, 20.0f);
System.out.println(result1);
System.out.println(result2);
System.out.println(result3);
}
}
2. Reference to an Instance Method
Like static methods, you can refer to instance methods also. In the following example, we are describing the process of referring to the instance method.
Syntax :
containingObject::instanceMethodName
Example 1: In the following example, we are referring to non-static methods. You can refer to methods by a class object and anonymous object.
public class ReferenceToInstanceMethod {
public void saySomething() {
System.out.println("Hello, this is non-static method.");
}
public static void main(String[] args) {
// Creating object
ReferenceToInstanceMethod methodReference = new ReferenceToInstanceMethod();
// Referring non-static method using reference
Sayable sayable = methodReference::saySomething;
// Calling interface method
sayable.say();
// Referring non-static method using anonymous object
// You can use anonymous object also
Sayable sayable2 = new ReferenceToInstanceMethod()::saySomething;
// Calling interface method
sayable2.say();
}
}
interface Sayable {
void say();
}
Example 2:
package com.java.lambda; import java.util.*; import java.util.function.BiFunction; import java.util.function.Function; @FunctionalInterface interface Printable{ void print(String msg); } public class MethodRefDemo { public void display(String msg){ System.out.println(msg); } public static void main(String[] args) { // 1. Method reference to an instance method of an object MethodRefDemo methodRefDemo = new MethodRefDemo(); Printable printableLambda = (String msg) -> methodRefDemo.display(msg); printableLambda.print("Hello"); Printable printable = methodRefDemo::display; printable.print("Hello"); // using lambda expression Function<String, String> lowerCaseFunction = (String input) -> input.toLowerCase(); String result = lowerCaseFunction.apply("Java Guides"); System.out.println(result); // using method references Function<String, String> lowerCaseFunctionRef = String::toLowerCase; String result1 = lowerCaseFunctionRef.apply("Java Guides"); System.out.println(result1); } }
Example 3: In the following example, we are using BiFunction interface. It is a predefined interface and contains a functional method to apply(). Here, we are referring to add a method to apply method.
import java.util.function.BiFunction;
class Arithmetic {
public int add(int a, int b) {
return a + b;
}
}
public class InstanceMethodReference3 {
public static void main(String[] args) {
BiFunction<Integer, Integer, Integer> adder = new Arithmetic()::add;
int result = adder.apply(10, 20);
System.out.println(result);
}
}
3. Reference to an Instance Method of an Arbitrary Object of a Particular Type
Sometimes, we call a method of 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.
Syntax :
ContainingType::methodName
Example: The following is an example of a reference to an instance method of an arbitrary object of a particular type:
String[] stringArray = { "Barbara", "James", "Mary", "John",
"Patricia", "Robert", "Michael", "Linda" };
Arrays.sort(stringArray, String::compareToIgnoreCase);
4. Reference to a Constructor
You can refer to a constructor by using the new keyword. Here, we are referring constructor with the help of a functional interface.
Syntax :
ClassName::new
Example 1: The below example demonstrates the usage of method reference to the constructor.
public class ReferenceToConstructor {
public static void main(String[] args) {
Messageable hello = Message::new;
hello.getMessage("Hello");
}
}
interface Messageable{
Message getMessage(String msg);
}
class Message{
Message(String msg){
System.out.print(msg);
}
}
Example 2: Write the Lambda to convert List into Set and convert Lambda into method reference:
// 4. reference to a constructor
List<String> fruits = new ArrayList<>();
// Adding new elements to the ArrayList
fruits.add("Banana");
fruits.add("Apple");
fruits.add("mango");
fruits.add("orange");
// Using lambda expression
Function<List<String>, Set<String>> f2 = (nameList) -> new HashSet<>(nameList);
Set<String> set2 = f2.apply(fruits);
System.out.println(set2);
// Using Method reference
Function<List<String>,Set<String>> f3= HashSet::new;
Set<String> set = f3.apply(fruits);
System.out.println(set);
Source code on GitHub
The source code of this post is available on GitHub Repository.
Related Java 8 Top Posts
- Java 8 Lambda Expressions
- Java 8 Functional Interfaces
- Java 8 Method References
- Java 8 Stream API
- Java 8 Optional Class
- Java 8 Collectors Class
- Java 8 StringJoiner Class
- Java 8 Static and Default Methods in Interface
- Guide to Java 8 forEach Method
- Handle NullPointerException in Controller, Service, and DAO Layer using Java 8 Optional Class
- How to Use Java 8 Stream API in Java Projects
- Migrating Source Code to Java 8
Comments
Post a Comment
Leave Comment