Master in the forEach() Method in Java 8
The forEach()
method is part of the Iterable
interface and is commonly used with collections (such as List, Set, etc.) and streams in Java. It takes a Consumer
as an argument and applies that consumer's action to each element in the collection.
Consumer Interface
A Consumer
is a functional interface introduced in Java 8, located in the java.util.function
package. It represents an operation that accepts a single input argument and returns no result. The Consumer interface has a single method, accept()
, which takes an input argument of a certain type and performs an action on it.
Syntax
Here’s the syntax of the forEach()
method:
void forEach(Consumer<? super T> action)
Where:
T
is the type of elements in the collection.action
is an instance of theConsumer
functional interface.
Example
Let’s illustrate the forEach()
method with an example:
Suppose we have a list of integers and we want to double each integer in the list and print the result:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// Using forEach to double each number and print the result
numbers.forEach(num -> System.out.println(num * 2));
In this example:
Using forEach
is a concise and expressive way to work with collections in Java 8, making code more readable and maintainable.
Since Java 8, the forEach() has been added in the following classes or interfaces:
Iterable interface — This makes Iterable.forEach() method available to all collection classes except Map
Map interface — This makes forEach() operation available to all map classes.
Stream interface — This makes forEach() and forEachOrdered() operations available to all types of streams.
Internally, the forEach() uses the enhanced for-loop for iterating through the collection items. So using the enhanced for-loop will give the same performance as forEach() method.
Topics Covered:
- Introduction to forEach in Java 8
- Iterating a Map
- Iterating a List
- Iterating a Set
- Iterating a Stream
- Using forEach with Consumer
- Exception Handling with forEach
- forEach vs forEachOrdered
- Comparing with Java 7 Loops
Introduction to forEach in Java 8
The forEach()
method introduced in Java 8 allows for concise iteration over collections, enhancing code readability and maintainability. It operates on streams and accepts a lambda expression or method reference to perform an action on each element.
Iterating a Map
The forEach()
method in the Map interface allows you to iterate over the entries (key-value pairs) of the map and perform a specified action on each entry.
Here’s the syntax of the forEach()
method in the Map interface:
void forEach(BiConsumer<? super K, ? super V> action)
Where:
K
is the type of keys in the map.V
is the type of values in the map.action
is an instance of theBiConsumer
functional interface, which represents an operation that accepts two input arguments (key and value) and returns no result.
Map<String, Integer> map = new HashMap<>();
map.put("apple", 1);
map.put("banana", 2);
map.put("orange", 3);
// Java 8 forEach
map.forEach((key, value) -> System.out.println(key + " -> " + value));
// Java 7 loop
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + " -> " + entry.getValue());
}
Iterating a List
List<String> list = Arrays.asList("apple", "banana", "orange");
// Java 8 forEach
list.forEach(item -> System.out.println(item));
// Java 7 loop
for (String item : list) {
System.out.println(item);
}
Iterating a Set
Set<Integer> set = new HashSet<>(Arrays.asList(1, 2, 3));
// Java 8 forEach
set.forEach(item -> System.out.println(item));
// Java 7 loop
for (Integer item : set) {
System.out.println(item);
}
Iterating a Stream
List<String> list = Arrays.asList("apple", "banana", "orange");
// Java 8 forEach on Stream
list.stream().forEach(item -> System.out.println(item));
// Java 7 loop on Stream
for (String item : list) {
System.out.println(item);
}
Using forEach with Null Check
list.forEach(item -> {
if (item != null) {
// Perform some action
}
});
Exception Handling with forEach
list.forEach(item -> {
try {
// Perform some operation that may throw an exception
} catch (Exception e) {
// Handle the exception
}
});
forEach vs forEachOrdered
list.stream().forEach(item -> System.out.println(item)); // May not maintain order
list.stream().forEachOrdered(item -> System.out.println(item)); // Maintains order
— Very Very Important —
What is the use of curly braces { } in forEach?
Using curly braces within the forEach
method in Java 8 allows you to include multiple statements or more complex logic within the lambda expression.
Here is the previous example refactored to use curly braces:
employeeList.stream()
.collect(Collectors.groupingBy
(Employee::getDepartment, Collectors.counting()))
.forEach((department, count) -> {
System.out.println("Department: " + department);
System.out.println("Number of Employees: " + count);
System.out.println("--------------------------");
});
In this version:
- Curly braces
{}
are used to define a block of code for the lambda expression. - Within the block, multiple statements are included to print additional information or format the output differently.
Conclusion:-
Comparing with Java 7 Loops
Java 8’s forEach
method offers a more concise and expressive syntax compared to traditional loops in Java 7. It eliminates boilerplate code and enhances code readability, making it the preferred choice for iterating over collections in modern Java programming.
By mastering forEach
and understanding its nuances, developers can write cleaner, more efficient code and leverage the full power of functional programming in Java.
Stay tuned for more Java tips and tricks!
Thanks & Happy Learning :)