In this article, we will understand forEach loop added in java 8 to iterate over Collections such as a list, set or map or over java streams with example programs.

Overview
forEach() is a method introduced in java 8 in java.lang.Iterable interface and can be used to iterate over a collection.
forEach() is a default interface method which takes a java.util.function.Consumer as argument.
Syntax of forEach() method is given below

void forEach(Consumer<? super T> action) { }

Using forEach()
forEach() accepts an argument of type Consumer. It is a functional interface and hence, contains a single method accept(), which takes a single argument and returns no value.
Signature of accept() method is

void accept(T t);

forEach() method is invoked on a collection and is invoked automatically for each element of the collection.
Thus, it can be said that for every element, accept() method of Consumer interface is invoked with a collection element as argument value.
We need to define implementation of accept() method as per our requirement.

There are 3 ways to implement accept() method.
1. Implement Consumer interface in a class
Create a class implmenting Consumer interface and hence, its accept() method as shown below.

public class ConsumerImpl implements Consumer<String> {
   @Override
   public void accept(String s) {
      System.out.println(s);
   }
}

Then, supply the object of this class to forEach() as below

list.forEach(new ConsumerImpl());

2. Anonymous Consumer Implementation
Instead of creating a separate class for implementing Consumer interface, define implementation of accept() method inline as an anonymous inner class as shown below

list.forEach(new Consumer<String>(){
   public void accept(String t) {
      System.out.println(t);
   }
});
Consumer is a generic interface. Type of Consumer and the type of argument of accept() method must be same, which is, String in above example.

3. As a Lambda expression
Since Consumer is a Functional interface, its accept() method can be implemented as a Lambda expression as shown below

list.forEach((t) -> {
   System.out.println(t);
});

In all examples of forEach(), we will be using lambda expression, since it makes the code concise and clean.

forEach() over list
A list can be iterated using forEach() as shown in the example below.

// define a list of integers
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// iterate with forEach
numbers.forEach(num -> {
      System.out.println(num);
});

forEach() over a stream
Java 8 streams can also be iterated using forEach() method. Example program is given below.

// define a list of integers
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// iterate over a stream
numbers.stream().forEach(
   num -> System.out.println(num)
);

forEach() over Map
forEach() method can be used to loop over a Map as shown below. java.util.Map interface defines a different forEach() method which takes a BiConsumer as argument.
java.util.function.BiConsumer is a Functional interface with a single method accept() that takes two arguments as shown below.

void accept(T t, U u);

When forEach() is invoked on a map, it internally invokes accept() method with key and value of current map element passed as arguments. Example,

Map<Integer, String> map = new HashMap<>();
map.put(1, "A");
map.put(2, "B");
map.put(3, "C");
map.forEach((k,v) -> {
    System.out.println("Key: " + k + ", Value: " + v);
});

This prints

Key: 1, Value: A
Key: 2, Value: B
Key: 3, Value: C

forEach() vs for-each
for-each, also known as enhanced for loop is compared with forEach() but both of these have differences. Following are the important differences summarized below.
1. forEach() is a method while for-each is a loop.
2. forEach() is introduced in java 1.8 while for-each loop was added in java 1.5.
3. You can supply lambda expresssion to forEach() but for-each loop doesn’t support lambda expressions.
4. Lambda expression used in forEach() loop cannot use non-final variables. Thus, below code is not allowed

int sum = 0;
list.forEach( x -> {
 // error: sum is not final
 sum += x;
});

While it is allowed in for-each loop.
5. You cannot use break statement in a lambda expression given in forEach() while it can be used in a for-each loop.

Hope the article was useful.

0