Java Method References
Introduction
Lambda expressions are used 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. Method references enable you to do this; they are compact, easy-to-read lambda expressions for methods that already have a name.
Basically it is a special type of lambda expression to call a method. The :: operator is used in method reference to separate the class or object from the method name.
Lambda Expression (parameters) -> methodName(parameters) can be written in Method Reference as [Object/Class]::methodName
Method References Are Abbreviated Lambdas
Example:
@FunctionalInterface interface Printer { void print(String str); } public class MethodReference { private static void lambdaWay() { Printer printer = (str) -> MethodReference.printHelloWorld(str); printer.print("@Lambda - Hello World!"); } private static void methodReferenceWay() { Printer printer = MethodReference::printHelloWorld; printer.print("@Method Reference - Hello World!"); } private static void printHelloWorld(String str) { System.out.println(str); } public static void main(String[] args) { lambdaWay(); methodReferenceWay(); } } Output: @Lambda - Hello World! @Method Reference - Hello World!
Types of Method References
- Reference to a static method
ContainingClass::staticMethodName
- Reference to an instance method of a particular object
containingObject::instanceMethodName
- Reference to an instance method of an arbitrary object of a particular type
ContainingType::methodName
- Reference to a constructor
ClassName::new
Reference to a static method
In the following example MethodReference::add is a reference to a static method.
interface Operator { int operate(int a, int b); } public class MethodReference { static int add(int a, int b) { return a+b; } public static void main(String[] args) { Operator operator = MethodReference::add; System.out.println("21 + 79 = " + operator.operate(21, 79)); } } Output: 21 + 79 = 100
Reference to an instance method of a particular object
In the following example methodReference::add is a reference to an instance method of a particular object
interface Operator { int operate(int a, int b); } public class MethodReference { int add(int a, int b) { return a+b; } public static void main(String[] args) { MethodReference methodReference = new MethodReference(); Operator operator = methodReference::add; System.out.println("21 + 79 = " + operator.operate(21, 79)); } } Output: 21 + 79 = 100
Reference to an Instance Method of an Arbitrary Object of a Particular Type
public class MethodReference { private static void print(String[] stringArray, String str) { System.out.println("----- " + str + " -----"); System.out.println(Arrays.toString(stringArray)); } public static void main(String[] args) { String[] stringArray = {"Eminem", "Charli Puth", "Beyonce", "Bruno Mars", "Taylor Swift", "Akon", "Mike Shinoda", "Cardi B", "Michael Jackson", "Selena Gomez"}; print(stringArray, "Unsorted array"); Arrays.sort(stringArray, String::compareToIgnoreCase); print(stringArray, "Sorted array"); } } Output: ----- Unsorted array ----- [Eminem, Charli Puth, Beyonce, Bruno Mars, Taylor Swift, Akon, Mike Shinoda, Cardi B, Michael Jackson, Selena Gomez] ----- Sorted array ----- [Akon, Beyonce, Bruno Mars, Cardi B, Charli Puth, Eminem, Michael Jackson, Mike Shinoda, Selena Gomez, Taylor Swift]
Reference to a Constructor
You can reference a constructor in the same way as a static method by using the name new.
public class MethodReference { static class Department { String name; Department(String name) { this.name = name; } } public static void main(String[] args) { String[] departments = {"CSE", "ECE", "EEE", "ISE", "ITE"}; List<Department> departmentList = Arrays.stream(departments) .map(Department::new) .collect(Collectors.toList()); departmentList.forEach(d -> System.out.printf("%s\t", d.name)); } } Output: CSE ECE EEE ISE ITE
All Method Reference in Action
Example:
AnimeUtil.java
public class AnimeUtil { public int compareByTitle(Anime a1, Anime a2) { return a1.title.compareTo(a2.title); } public int compareByRating(Anime a1, Anime a2) { return a1.rating.compareTo(a2.rating); }
}
Anime.java
public class Anime { String title; Double rating; Anime(String title, Double rating) { this.title = title; this.rating = rating; } public static void print(Anime a) { System.out.printf("%-20s %.1f \n", a.title, a.rating); }
}
MethodReferenceExample.java
public class MethodReferenceExample { public static void main(String[] args) { List<Anime> animes = List.of( new Anime("Naruto", 8.3), new Anime("Fullmetal Alchemist", 9.1), new Anime("One Punch Man", 8.8), new Anime("Death Note", 9.0), new Anime("Code Geass", 8.6), new Anime("One Piece", 8.7)); System.out.println("----- My anime list -----"); animes.forEach(Anime::print); AnimeUtil animeUtil = new AnimeUtil(); System.out.println("----- Anime sort by title -----"); animes.stream() .sorted(animeUtil::compareByTitle) .forEach(Anime::print); System.out.println("----- Anime sort by rating -----"); animes.stream() .sorted(animeUtil::compareByRating) .forEach(Anime::print); } } Output: ----- My anime list ----- Naruto 8.3 Fullmetal Alchemist 9.1 One Punch Man 8.8 Death Note 9.0 Code Geass 8.6 One Piece 8.7 ----- Anime sort by title ----- Code Geass 8.6 Death Note 9.0 Fullmetal Alchemist 9.1 Naruto 8.3 One Piece 8.7 One Punch Man 8.8 ----- Anime sort by rating ----- Naruto 8.3 Code Geass 8.6 One Piece 8.7 One Punch Man 8.8 Death Note 9.0 Fullmetal Alchemist 9.1
References
More Links
Thanks for reading. Please like & share the article.