forEach Method in Java
The forEach method in Java is used to perform an action on every element of a collection. It takes a lambda (a Consumer) and calls it once for each element, so you don't have to write a loop. forEach was added in Java 8 to the Iterable interface (so every List, Set and Queue has it), to Map (with a two-argument lambda), and to streams. In this lesson, you will learn each version and when a normal loop is still the better choice.
Declaration
// in Iterable<T>
default void forEach(Consumer<? super T> action)
// in Map<K, V>
default void forEach(BiConsumer<? super K, ? super V> action)
// in Stream<T>
void forEach(Consumer<? super T> action)Example: forEach on a List, a Set and a Map
Let's see an example of each.
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
public class ForEachDemo {
public static void main(String[] args) {
List<String> names = List.of("Navika", "Srihitha", "Advitha");
names.forEach(n -> System.out.println("Hello " + n));
new TreeSet<>(names).forEach(System.out::println);
Map<String, Integer> marks = new LinkedHashMap<>();
marks.put("Navika", 91);
marks.put("Srihitha", 78);
marks.forEach((name, m) -> System.out.println(name + " scored " + m));
}
}Hello Navika
Hello Srihitha
Hello Advitha
Advitha
Navika
Srihitha
Navika scored 91
Srihitha scored 78Explanation: List.forEach runs the lambda for each name in order. TreeSet.forEach visits the names in sorted order, here with a method reference. Map.forEach passes the key and the value to a two-parameter lambda.
forEach vs a For-Each Loop
forEach(...) method | for-each loop | |
|---|---|---|
break or continue | Not possible | Possible |
return from the enclosing method | Not possible (only from the lambda) | Possible |
| Changing local variables | Not allowed (must be effectively final) | Allowed |
| Checked exceptions inside | Must be caught in the lambda | Can be thrown |
| Best for | One short action per element | Anything more complex |
Example: Stream forEach and Ordering
import java.util.List;
public class StreamForEach {
public static void main(String[] args) {
List<Integer> marks = List.of(91, 38, 85, 42);
marks.stream()
.filter(m -> m >= 50)
.forEach(m -> System.out.println("Pass: " + m));
marks.stream()
.sorted()
.forEachOrdered(m -> System.out.print(m + ";"));
System.out.println();
}
}Pass: 91
Pass: 85
38;42;85;91;Explanation: forEach at the end of a stream acts on each element that survives the pipeline. forEachOrdered guarantees the stream's order even if the stream were parallel; on a parallel stream, plain forEach may visit elements in any order.
Common Mistakes
Calling list.remove(...) inside list.forEach(...). It throws ConcurrentModificationException; use removeIf.
Trying to break out of forEach. It isn't possible; use a loop or a stream with takeWhile or anyMatch.
Adding to an outside list from stream().forEach. Use collect or toList(), which also work correctly in parallel.
Practice
- Easy: Use
forEachto print each element of a list of prices with a currency symbol. - Harder: Given a
Map<String, List<Integer>>of student marks, useMap.forEachto print each student's average.
Key Takeaways
Was this tutorial helpful?