The forEach() method in Java is a utility function to iterate over a Collection (list, set or map) or Stream. The forEach() performs a given Consumer action on each item in the Collection.
List<String> list = Arrays.asList("Alex", "Brian", "Charles");
list.forEach(System.out::println);
1. Introduction
Since Java 8, the forEach()
has been added in the following classes or interfaces:
Iterable
interface – This makesIterable.forEach()
method available to all collection classes exceptMap
Map
interface – This makesforEach()
operation available to all map classes.Stream
interface – This makesforEach()
andforEachOrdered()
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.
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
2. Using forEach() with List or Set
The forEach()
method performs the given action
for each element of the List
(or Set) until all elements have been processed or the action
throws an exception.
In the following example, System.out::println is a Consumer action representing an operation that accepts a single input argument and returns no result. It is an instance of Consumer
interface. When used with list.forEach(), the program prints all the list items in the console one by one.
List<String> list = Arrays.asList("Alex", "Brian", "Charles");
list.forEach(System.out::println);
The program output.
Alex
Brian
Charles
We can also create custom Consumer action that can execute multiple statements or perform complex logic. In the following example, the action makeUpperCase converts the argument string to UPPERCASE.
Consumer<String> makeUpperCase = new Consumer<String>() {
@Override
public void accept(String t) {
//More statements if needed
System.out.println(t.toUpperCase());
}
};
List<String> list = Arrays.asList("Alex", "Brian", "Charles");
list.forEach(makeUpperCase);
The program output:
ALEX
BRIAN
CHARLES
3. Using Map.forEach()
When used with Map, forEach() method performs the given BiConsumer action for each Entry
in Map
until all entries have been processed or the action throws an exception.
Map<String, String> map = Map.of("A", "Alex", "B", "Brian", "C", "Charles");
map.forEach((k, v) -> System.out.println("Key = " + k + ", Value = " + v));
The program output:
Key = A, Value = Alex
Key = B, Value = Brian
Key = C, Value = Charles
We can also create a custom BiConsumer action which will take key-value pairs from Map
and process each entry one at a time.
BiConsumer<String, Integer> action = (a, b) -> {
System.out.println("Key is : " + a);
System.out.println("Value is : " + b);
};
Map<String, Integer> map = Map.of("A", 1, "B", 2, "C", 3);
map.forEach(action);
Program output.
Key is : A
Value is : 1
Key is : B
Value is : 2
Key is : C
Value is : 3
4. Using Stream.forEach() and Stream.forEachOrdered()
In Stream
, forEach()
and forEachOrdered()
are terminal operations. Similar to Iterable
, stream forEach()
performs an action for each element of the Stream.
- For sequential streams, the order of elements (during iteration) is same as the order in the stream source, so the output would be the same whether we use
forEach()
orforEachOrdered()
. - For parallel streams, use
forEachOrdered()
if the order of the elements matters during the iteration. The forEach() method does not guarantee the element ordering to provide the advantages of parallelism.
In this example, we are printing all the even numbers from a stream of numbers.
List<Integer> numberList = List.of(1,2,3,4,5);
Consumer<Integer> action = System.out::println;
numberList.stream()
.filter(n -> n%2 == 0)
.forEach( action );
Program output.
2
4
Similarly, we can use the forEachOrdered() with parallel streams. Use it for considerably large streams.
List<Integer> numberList = List.of(1,2,3,4,5);
Consumer<Integer> action = System.out::println;
numberList.stream()
.filter(n -> n%2 != 0)
.parallel()
.forEachOrdered( action );
Program output.
1
3
5
5. Conclusion
In this Java 8 tutorial, we learned to use the forEach() method for iterating though the items in Java Collections and/or Streams. We leaned to perform Consumer and BiConsumer action in form of annonymous methods as well as lambda expressions.
Happy Learning !!