# How Does the “forEach()” Loop Work in Java?

Java 8 has introduced many features and the `forEach()` method is one of them.

The `forEach()` method is a way to iterate over a Collection (for example, a map, a set or a list) or a [Stream](https://techwithmaddy.com/java-8-streams).

The `forEach()` takes only one parameter, which is a [functional interface](https://techwithmaddy.com/java-8-functional-interfaces). This means that you can use a [lambda expression](https://techwithmaddy.com/java-8-lambda-expression) as an argument.

Let's see examples to understand how the `forEach()` works on Collections and Streams.

## **forEach() on a list**

```java
import java.util.ArrayList;
import java.util.List;

public class Fruit {

    public static void main(String[] args) {

        List<String> listOfFruits = new ArrayList<>();
        listOfFruits.add("apple");
        listOfFruits.add("pear");
        listOfFruits.add("banana");
        listOfFruits.add("mango");

        //using a lambda expression
        listOfFruits.forEach(x -> System.out.println(x));

        //using a method reference
        listOfFruits.forEach(System.out::println);

    }
}
```

The outcome in both cases is:

```java
apple
pear
banana
mango
```

In the code snippet above, we are:

* Creating a List called `listOfFruits`.
    
* Adding items to the list.
    
* Looping through the items and printing them using a lambda expression or a method reference.
    

## **forEach() on a map**

```java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Fruit {

    public static void main(String[] args) {

        Map<Integer, String> mapOfFruits = new HashMap<>();
        mapOfFruits.put(1, "apple");
        mapOfFruits.put(2, "pear");
        mapOfFruits.put(3, "banana");
        mapOfFruits.put(4, "mango");

        mapOfFruits.forEach((x, y) -> System.out.println(x + " " + y));

    }
}
```

The outcome is:

```plaintext
1 apple
2 pear
3 banana
4 mango
```

In the code snippet above, we are:

* Creating a `mapOfFruits` with Integer as the key and String as the value.
    
* Populating the map with different fruits. For example, key 1 is linked to apple. And so on.
    
* Looping through the items and printing their keys and values using a lambda expression.
    

**forEach() on a set**

```java
import java.util.HashSet;
import java.util.Set;

public class Fruit {

    public static void main(String[] args) {

        Set<String> setOfFruits = new HashSet<>();

        setOfFruits.add("apple");
        setOfFruits.add("pear");
        setOfFruits.add("banana");
        setOfFruits.add("mango");
        
        setOfFruits.forEach(x -> System.out.println(x));

    }
}
```

The outcome is:

```plaintext
banana
apple
pear
mango
```

In the code snippet above, we are:

* Creating a `setOfFruits`.
    
* Adding fruits to the set.
    
* Looping through the items and printing them using a lambda expression.
    

**NOTE**: a Set doesn't guarantee any order. Also, it doesn't accept duplicates. If you add another "mango", you won't get any compilation error, but it won't print out the second "mango".

## **forEach() on a stream**

```java
import java.util.ArrayList;
import java.util.List;

public class Fruit {

    public static void main(String[] args) {

        List<String> listOfFruits = new ArrayList<>();
        listOfFruits.add("apple");
        listOfFruits.add("pear");
        listOfFruits.add("banana");
        listOfFruits.add("mango");

        listOfFruits.stream()
                .forEach(x -> System.out.println(x));
    }
}
```

## forEach() to print a filtered list of items

```java
import java.util.ArrayList;
import java.util.List;

public class Fruit {

    public static void main(String[] args) {

        List<String> listOfFruits = new ArrayList<>();
        listOfFruits.add("apple");
        listOfFruits.add("pear");
        listOfFruits.add("banana");
        listOfFruits.add("mango");

        listOfFruits.stream()
                .filter(x -> x.length() == 5)
                .forEach(x -> System.out.println(x));
    }
}
```

The outcome is:

```plaintext
apple
mango
```

In the code snippet above, we are:

* Creating a `listOfFruits`.
    
* Adding fruits to the list.
    
* Using the Stream API to filter out those fruits whose length equals 5.
    
* Looping through the filtered list and printing the items using a lambda expression.
    

## forEach() vs forEachOrdered()

If you want to ensure that the items are printed in order, you can use the `forEachOrdered()` method. This method is a terminal operator.

The `forEach()` always goes at the end of a Stream because there is nothing to return after its execution. The same goes for the `forEachOrdered()` method.

Let's look at an example to understand this better:

```java
import java.util.Arrays;
import java.util.List;

public class Fruit {

    public static void main(String[] args) {

        List<String> listOfFruits = Arrays.asList("apple", "mango", "pear", "banana");

        //using forEach()
        listOfFruits.stream().parallel().forEach(System.out::println);
        System.out.println("-------------------");
        // using forEachOrdered()
        listOfFruits.stream().parallel().forEachOrdered(System.out::println);

    }
}
```

The outcome is:

```plaintext
pear
banana
apple
mango
-------------------
apple
mango
pear
banana
```

## What is the difference between a forEach() And a forEachOrdered()?

When using parallelism (in short, when things run simultaneously) on a `forEach()`, the order of items is not guaranteed. The `forEachOrdered()` is a way to explicitly say that you want to maintain the order of encounter, and indeed, the items are printed that way.

## What are the advantages of using a forEach() Loop?

* **The code is more readable**: if you compare the `forEach(`) with a regular for loop, the `forEach()` is more readable and concise because you don't have to declare the initialization, condition and increment or decrement.
    
* **It's bug-free**.
    

## Conclusion

I hope you've found this article helpful to you!

Until next time!

🙋🏾‍♀️
