Main Tutorials

Java 8 forEach examples

In Java 8, we can use the new forEach to loop or iterate a Map, List, Set, or Stream.

Topics

  1. Loop a Map
  2. Loop a List
  3. forEach and Consumer
  4. forEach and Exception handling
  5. forEach vs forEachOrdered

1. Loop a Map

1.1 Below is a normal way to loop a Map.


  public static void loopMapClassic() {

      Map<String, Integer> map = new HashMap<>();
      map.put("A", 10);
      map.put("B", 20);
      map.put("C", 30);
      map.put("D", 40);
      map.put("E", 50);
      map.put("F", 60);

      for (Map.Entry<String, Integer> entry : map.entrySet()) {
          System.out.println("Key : " + entry.getKey() + ", Value : " + entry.getValue());
      }

  }

1.2 In Java 8, we can use forEach to loop a Map and print out its entries.


  public static void loopMapJava8() {

      Map<String, Integer> map = new HashMap<>();
      map.put("A", 10);
      map.put("B", 20);
      map.put("C", 30);
      map.put("D", 40);
      map.put("E", 50);
      map.put("F", 60);

      // lambda
      map.forEach((k, v) -> System.out.println("Key : " + k + ", Value : " + v));

  }

Output

Terminal

Key : A, Value : 10
Key : B, Value : 20
Key : C, Value : 30
Key : D, Value : 40
Key : E, Value : 50
Key : F, Value : 60

1.3 For the Map‘s key or value containing null, the forEach will print null.


  public static void loopMapJava8() {

      Map<String, Integer> map = new HashMap<>();
      map.put("A", 10);
      map.put("B", 20);
      map.put("C", 30);
      map.put(null, 40);
      map.put("E", null);
      map.put("F", 60);

      // ensure map is not null
      if (map != null) {
          map.forEach((k, v) -> System.out.println("Key : " + k + ", Value : " + v));
      }

  }

Output

Terminal

Key : null, Value : 40
Key : A, Value : 10
Key : B, Value : 20
Key : C, Value : 30
Key : E, Value : null
Key : F, Value : 60

P.S The normal way to loop a Map will print the same above output.

1.4 If we do not want to print the null key, add a simple null checking inside the forEach.


  public static void loopMapJava8() {

      Map<String, Integer> map = new HashMap<>();
      map.put("A", 10);
      map.put("B", 20);
      map.put("C", 30);
      map.put(null, 40);
      map.put("E", null);
      map.put("F", 60);

      map.forEach(
          (k, v) -> {
              // yes, we can put logic here
              if (k != null){
                  System.out.println("Key : " + k + ", Value : " + v);
              }
          }
      );

  }

Output

Terminal

Key : A, Value : 10
Key : B, Value : 20
Key : C, Value : 30
Key : E, Value : null
Key : F, Value : 60

2. Loop a List

2.1 Below is a normal way to loop a List.


  public static void loopListClassic() {

      List<String> list = new ArrayList<>();
      list.add("A");
      list.add("B");
      list.add("C");
      list.add("D");
      list.add("E");

      // normal loop
      for (String l : list) {
          System.out.println(l);
      }

  }

2.2 Java 8 forEach to loop a List.


  public static void loopListJava8() {

      List<String> list = new ArrayList<>();
      list.add("A");
      list.add("B");
      list.add("C");
      list.add("D");
      list.add("E");

      // lambda
      // list.forEach(x -> System.out.println(x));

      // method reference
      list.forEach(System.out::println);
  }

Output

Terminal

A
B
C
D
E

2.3 This example filters the null value of a List.


  public static void loopListJava8() {

      List<String> list = new ArrayList<>();
      list.add("A");
      list.add("B");
      list.add(null);
      list.add("D");
      list.add("E");

      // filter null value
      list.stream()
              .filter(Objects::nonNull)
              .forEach(System.out::println);

  }

Output

Terminal

A
B
D
E

P.S The forEach for Set and Stream works the same way.

3. forEach and Consumer

3.1 Review the forEach method signature, it accepts a functional interface Consumer.

Iterable.java

public interface Iterable<T> {

  default void forEach(Consumer<? super T> action) {
      Objects.requireNonNull(action);
      for (T t : this) {
          action.accept(t);
      }
  }
  //..
}
Stream.java

public interface Stream<T> extends BaseStream<T, Stream<T>> {

  void forEach(Consumer<? super T> action);
  //...

}

3.2 This example creates a Consumer method to print String to its Hex format. We can now reuse the same Consumer method and pass it to the forEach method of List and Stream.

ForEachConsumer.java

package com.mkyong.java8.misc;

import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Stream;

public class ForEachConsumer {

    public static void main(String[] args) {

        List<String> list = Arrays.asList("abc", "java", "python");
        Stream<String> stream = Stream.of("abc", "java", "python");

        // convert a String to a Hex
        Consumer<String> printTextInHexConsumer = (String x) -> {
            StringBuilder sb = new StringBuilder();
            for (char c : x.toCharArray()) {
                String hex = Integer.toHexString(c);
                sb.append(hex);
            }
            System.out.print(String.format("%n%-10s:%s", x, sb.toString()));
        };

        // pass a Consumer
        list.forEach(printTextInHexConsumer);

        stream.forEach(printTextInHexConsumer);

    }

}

Output

Terminal

abc       :616263
java      :6a617661
python    :707974686f6e

abc       :616263
java      :6a617661
python    :707974686f6e

4. forEach and Exception handling.

4.1 The forEach is not just for printing, and this example shows how to use forEach method to loop a list of objects and write it to files.

ForEachWriteFile.java

package com.mkyong.java8.misc;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;

public class ForEachWriteFile {

    public static void main(String[] args) {

        ForEachWriteFile obj = new ForEachWriteFile();
        obj.save(Paths.get("C:\\test"), obj.createDummyFiles());
    }

    public void save(Path path, List<DummyFile> files) {

        if (!Files.isDirectory(path)) {
            throw new IllegalArgumentException("Path must be a directory");
        }

        files.forEach(f -> {
            try {
                int id = f.getId();
                // create a filename
                String fileName = id + ".txt";
                Files.write(path.resolve(fileName),
                        f.getContent().getBytes(StandardCharsets.UTF_8));
            } catch (IOException e) {
                e.printStackTrace();
            }
        });

    }

    public List<DummyFile> createDummyFiles() {
        return Arrays.asList(
                new DummyFile(1, "hello"),
                new DummyFile(2, "world"),
                new DummyFile(3, "java"));
    }

    class DummyFile {
        int id;
        String content;

        public DummyFile(int id, String content) {
            this.id = id;
            this.content = content;
        }

        public int getId() {
            return id;
        }

        public String getContent() {
            return content;
        }
    }
}

The above program will create three text files.

C:\\test\\1.txt

hello
C:\\test\\2.txt

world
C:\\test\\3.txt

java

4.2 The Files.write may throws IOException, and we must catch the exception inside the forEach; thus, the code looks ugly. The common practice is to extract the code to a new method.


  public void save(Path path, List<DummyFile> files) {

      if (!Files.isDirectory(path)) {
          throw new IllegalArgumentException("Path must be a directory");
      }

      // extract it to a new method
      /*files.forEach(f -> {
            try {
                int id = f.getId();
                // create a filename
                String fileName = id + ".txt";
                Files.write(path.resolve(fileName),
                        f.getContent().getBytes(StandardCharsets.UTF_8));
            } catch (IOException e) {
                e.printStackTrace();
            }
        });*/

      // nice!
      files.forEach(f -> saveFile(path, f));

  }

  public void saveFile(Path path, DummyFile f) {
      try {
          int id = f.getId();
          // create a filename
          String fileName = id + ".txt";
          Files.write(path.resolve(fileName),
                  f.getContent().getBytes(StandardCharsets.UTF_8));
      } catch (IOException e) {
          e.printStackTrace();
      }
  }

Now, we also can write code like this:


  ForEachWriteFile obj = new ForEachWriteFile();

  Path path = Paths.get("C:\\test");
  obj.createDummyFiles().forEach(o -> obj.saveFile(path, o));

5. forEach vs forEachOrdered

5.1 The forEach does not guarantee the stream’s encounter order, regardless of whether the stream is sequential or parallel. The result is obvious when run in a parallel mode.


  Stream<String> s = Stream.of("a", "b", "c", "1", "2", "3");
  s.parallel().forEach(x -> System.out.println(x));

Each run will generate different result:

Terminal

1
2
b
c
3
a

5.2 The forEachOrdered guarantees the stream’s encounter order; thus, it sacrifices the benefit of parallelism.


  Stream<String> s = Stream.of("a", "b", "c", "1", "2", "3");
  // keep order, it is always a,b,c,1,2,3
  s.parallel().forEachOrdered(x -> System.out.println(x));

The result is always a,b,c,1,2,3

Terminal

a
b
c
1
2
3

Download Source Code

$ git clone https://github.com/mkyong/core-java

$ cd java8

References

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
21 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Phani
7 years ago

Hi:

I keep learning a lot from your examples.. they are simple and to the point..thank you and keep it up.

robertmarkbram
8 years ago

Good page. Clear and simple examples. Thanks!

Edu
5 years ago

The only think I don’t like using forEach is when you want to call inside it a service that throws exceptions, because you must catch them inside forEach loop. It doesn’t happen with “for” sentence, as you can have the try outside it.

Josh
6 years ago

Clear and simple examples.
Keep it up!

jas
7 months ago

Thanks for the additional examples. This was the most thorough tutorial I’ve seen, and the only one to address the need for null checks.

Prasanta Kumar
2 years ago

and I am always watching your example when I am getting error in my work.

Prasanta Kumar
2 years ago

Hi mkyong,
given all examples are simple and point to point, Thanks a lot.

Last edited 2 years ago by Prasanta Kumar
storm
2 years ago

forEach() is orderd ,while parallel() may not

Unless otherwise specified by the implementing class,
* actions are performed in the order of iteration (if an iteration order
* is specified)
RAVISHANKER NEMALA
3 years ago

can you please give me some examples how to replace the items in the list using Stream().

Sheetal Singh
4 years ago

Hi Mkyong,

I really inspired by your way of explanation, very simple to understand.

ash
5 years ago

Great examples. Thanks.

Kiran U
5 years ago

It really helped me.. thank you so much

Vijay
6 years ago

Thanks, I was iterating a forEeah loop and instead of sysout. I want to perform few operations but I was getting an error. Your post help me identify what should I do.

tms
6 years ago

hello, thanks for this tutorial. In Java 8 possible to use ‘::’ ?
items.forEach(System.out::println);

tms
6 years ago
Reply to  tms

I checked it. It is equals the– items.forEach(item->System.out.println(item)); –?
Because the parameter and the return type is the same?
Sorry for dump question .

Reader
7 years ago

When I do this, I am getting a null pointer exception when the value in the map is null (v is null). How can I avoid that?

items.forEach((k,v)->System.out.println(“Item : ” + k + ” Count : ” + v));

DucQuoc.wordpress.com
6 years ago
Reply to  Reader

Optional.ofNullable(items).orElse(Collections.emptyMap())
.forEach((k, v) -> System.out.println(“Item : ” + k + ” Count : ” + v));

Casey
6 years ago
Reply to  Reader

if (items != null) items.forEach((k,v)->System.out.println(“Item : ” + k + ” Count : ” + v));