Java forEach()

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 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.

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() or forEachOrdered().
  • 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 !!

Comments

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.