Java is a popular programming language used in a variety of applications. It provides several built-in methods to simplify coding and increase efficiency. One such method is the forEach() method, which is part of the Iterable interface in Java. This method is used to iterate through a collection and takes an argument of Consumer type interface. The Consumer interface is a functional interface with only one abstract method called accept(). Since it is a functional interface, a lambda expression can be passed.
Let's take a look at an example that illustrates the use of lambda expression in the forEach() method. In the following code, we use the lambda expression to print the elements inside a collection:
javaimport java.util.*;
class GfG {
public static void main(String args[]) {
List<Integer> al = Arrays.asList(10, 20, 15, 16);
al.forEach(x -> System.out.println(x));
}
}
In this example, we have created an ArrayList and passed a lambda expression to the forEach() method to print each element inside the list. The output of this code will be:
10 20 15 16
We can modify the above code using method reference, which simplifies the code even further. When a lambda expression is simply used for a pass-through operation, it can be replaced by a method reference. Let's take a look at the following example:
javaimport java.util.*;
class GfG {
public static void main(String args[]) {
List<Integer> al = Arrays.asList(10, 20, 15, 16);
al.forEach(System.out::println);
}
}
In this example, we have replaced the lambda expression with a method reference to simplify the code. The output of this code will be the same as the previous example:
10 20 15 16
It is important to note that when a lambda expression takes a parameter or multiple parameters and calls a function with the same parameter, a method reference can be used instead of writing the complex lambda expression. Let's take a look at the following example:
typescriptimport java.util.*;
class GfG {
public static void main(String args[]) {
List<Integer> al = Arrays.asList(10, 20, 7, 8);
al.forEach(GfG::printSquare);
}
public static void printSquare(Integer x) {
System.out.println(x*x);
}
}
In this example, we have used a static method to print the square of each element in the list. We have also passed the method reference to the forEach() method to simplify the code. The output of this code will be:
100 400 49 64
In addition, we can also use method reference with the Comparator interface to compare two strings. The Comparator interface is a functional interface that allows us to compare two objects based on a specific criteria. In the following example, we use the Arrays.equals() method to compare two arrays of strings and pass the method reference as the Comparator interface to ignore the cases while comparison:
typescriptimport java.util.*;
class GfG {
public static void main(String args[]) {
String a[] = {"GfG", "IDE", "Courses"};
String b[] = {"gfg", "ide", "courses"};
if(Arrays.equals(a, b, String::compareToIgnoreCase))
System.out.println("Yes");
else
System.out.println("No");
}
}
In this example, we have used the String::compareToIgnoreCase method reference to ignore the cases while comparing the two arrays. The output of this code will be:
yamlYes
It is important to note that the use of method references can lead to more concise and readable code. In addition, method references can also improve the performance of your code in certain cases. When a lambda expression is used repeatedly, creating a new instance of the lambda for each use can create unnecessary overhead. By using a method reference instead, you can reduce the amount of object creation and improve the overall performance of your code.
There are several types of method references in Java, including:
Reference to a static method: This type of method reference refers to a static method of a class. It can be expressed using the Classname::methodname syntax.
Reference to an instance method of a particular object: This type of method reference refers to an instance method of a particular object. It can be expressed using the objectname::methodname syntax.
Reference to an instance method of an arbitrary object of a particular type: This type of method reference refers to an instance method of an arbitrary object of a particular type. It can be expressed using the Classname::methodname syntax.
Reference to a constructor: This type of method reference refers to a constructor of a class. It can be expressed using the Classname::new syntax.
Let's take a closer look at each of these types of method references.
- Reference to a static method: A static method is a method that belongs to a class rather than an instance of the class. When you use a reference to a static method, you can specify the name of the class and the name of the method that you want to call. Here's an example of using a reference to a static method:
typescriptpublic class Main {
public static void print(String s) {
System.out.println(s);
}
public static void main(String[] args) {
List<String> strings = Arrays.asList("apple", "banana", "cherry");
strings.forEach(Main::print);
}
}
In this example, the print() method is a static method of the Main class. We pass this method reference to the forEach() method of the List interface to print each element of the list.
- Reference to an instance method of a particular object: An instance method is a method that belongs to an instance of a class rather than the class itself. When you use a reference to an instance method of a particular object, you can specify the name of the object and the name of the method that you want to call. Here's an example:
typescriptpublic class Main {
public void print(String s) {
System.out.println(s);
}
public static void main(String[] args) {
List<String> strings = Arrays.asList("apple", "banana", "cherry");
Main main = new Main();
strings.forEach(main::print);
}
}
In this example, the print() method is an instance method of the Main class. We create an instance of the Main class and pass a reference to its print() method to the forEach() method of the List interface to print each element of the list.
- Reference to an instance method of an arbitrary object of a particular type: An instance method of an arbitrary object of a particular type is a method that belongs to any instance of a class that implements a particular interface or extends a particular class. When you use a reference to an instance method of an arbitrary object of a particular type, you can specify the name of the class and the name of the method that you want to call. Here's an example:
typescriptpublic class Main {
public void print(String s) {
System.out.println(s);
}
public static void main(String[] args) {
List<String> strings = Arrays.asList("apple", "banana", "cherry");