Tuesday, October 19, 2021

10 Examples of forEach() method in Java 8

From Java 8 onward, you can iterate over a List or any Collection without using any loop in Java. The new Stream class provides a forEach() method, which can be used to loop over all or selected elements of the list and map. The forEach() method provides several advantages over the traditional for loop e.g. you can execute it in parallel by just using a parallel Stream instead of a regular stream. Since you are operating on stream, it also allows you to filter and map elements. Once you are done with filtering and mapping, you can use forEach() to operate over them. You can even use the method reference and lambda expression inside the forEach() method, resulting in a more clear and concise code.


If you have not started with Java 8 yet then you should make it one of your new year resolution for this year.  In the years to come, you will see much more adoption of Java 8. If you are looking for a good book to learn Java 8, then you can use Java 8 in Action, one of the best books about lambda expression, stream, and other functional aspects of Java 8.

And, if you are new to the Java world then I suggest you start learning from Java 8 itself, no need to learn from the old Java version, and using age-old techniques of doing a common task like sorting a list or map, working with date and time, etc.

If you need some help, you can also look at these free and comprehensive online Java courses which will not only teach you all this but much more. It's also the most up-to-date course, always updated to cover the latest Java versions like Java 11.

For now, let's see a couple of examples of forEach() in Java 8.




How to use forEach() method in Java 8

Now you know a little bit about the forEach() method and Java 8, it's time to see some code examples and explore more of the forEach() method in JDK 8.


1. Iterating over all elements of List using forEach()

You can loop over all elements using the Iterable.forEach() method as shown below:
List<String> alphabets 
     = new ArrayList<>(Arrays.asList("aa", "bbb", "cat", "dog"));
alphabets.forEach(s -> System.out.println(s));

This code will print every element of the list called alphabets. You can even replace lambda expression with method reference because we are passing the lambda parameter as it is to the
System.out.println() method as shown below:

 alphabets.forEach(System.out::println);
 
Now, let's see if you want to add a comma between two elements then you can do so by using lambda parameters as shown in the following example

alphabets.forEach(s -> System.out.print(s + ","));

Btw, now you cannot use method reference now because we are doing something with lambda parameters. Let's see another example of the forEach() method for doing filtering of elements. If you want to learn more about loops in Java, The Complete Java MasterClass is the most comprehensive course for Java programmers.



2. filter and forEach() Example

One of the main features of Stream API is its capability to filter elements based upon some conditions. We have already seen a glimpse of the powerful feature of Stream API in my earlier post, how to use Stream API in Java 8, here we will see it again but in the context of the forEach() method.

let's now only print elements that start with "a", following code will do that for you, startWith() is a method of String class, which return true if String is starting with String "a" or it will return false. Once the list is filtered then forEach() method will print all elements starting with  String "a", as shown below:

alphabets.stream()
         .filter(s -> s.startsWith("a"))
         .forEach(System.out::println);
   

This is cool, right? You can read the code like cake, it's much easier than using Iterator or any other way to loop over List in Java.

Now, let's filter out only which has a length greater than 2, for this purpose we can use the length() function of String class:
alphabets.stream()
         .filter(s -> s.length() > 2)
         .forEach(System.out::println);


Apart from forEach, this is also a good example of using the filter method in Java 8 for filtering or selecting a subset of elements from Stream. You can read more about that in the Collections to Streams in Java 8 Using the Lambda Expressions course on Pluralsight, which provides an in-depth explanation of new Java 8 features.





3. forEach() and map() Example

So far you have both basic and advanced examples of using the forEach() method, first with simply iterating over each element and then along with using the filter() method, Let's see one more example of the forEach() method along with the map() function, which is another key functionality of Stream API.

The map() method of Java 8 allows you to transform one type to another like in our first example we are using a map() to transform a list of String to a list of Integer where each element represents the length of String. Now, let's print the length of each string using the map() function:
alphabets.stream()
         .mapToInt(s -> s.length())
         .forEach(System.out::println);
   
That was fun, isn't it? how about the calculating sum of the length of all strings? you can do so by using fold operations like sum() as shown in the following example:

alphabets.stream()
         .mapToInt(s -> s.length())
         .sum();

These were some of the common but very useful examples of Java 8's forEach() method, a new way to loop over List in Java. If you are feeling nostalgist then don't forget to the journey of for loop in Java, a recap of for loop from JDK 1 to JDK 8

If you want to learn more about functional programming in Java 8 and using a map, flatmap methods then I suggest you go through Learn Java Functional Programming with Lambdas & Streams course on Udemy. It's a nice course and packed with good examples to learn key Java 8 features.




Program to use forEach() function in Java 8

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Java Program to show How to use forEach() statement in Java8.
 * You can loop over a list, set or any collection using this
 * method. You can even do filtering and transformation and 
 * can run the loop in parallel.
 *
 * @author WINDOWS 8
 */
public class Java8Demo {

    public static void main(String args[]) {

       List<String> alphabets = new ArrayList<>(
                                 Arrays.asList("aa", "bbb", "cac", "dog"));
       
       // looping over all elements using Iterable.forEach() method
       alphabets.forEach(s -> System.out.println(s));
       
       // You can even replace lambda expression with method reference
       // because we are passing the lambda parameter as it is to the
       // method
       alphabets.forEach(System.out::println);
       
       // you can even do something with lambda parameter e.g. adding a comma
       alphabets.forEach(s -> System.out.print(s + ","));
       
       
       // There is one more forEach() method on Stream class, which operates
       // on stream and allows you to use various stream methods e.g. filter()
       // map() etc
       
       alphabets.stream().forEach(System.out::println);
       
       // let's now only print elmements which startswith "a"
       alphabets.stream()
               .filter(s -> s.startsWith("a"))
               .forEach(System.out::println);
       
       // let's filter out only which has length greater than 2
       alphabets.stream()
               .filter(s -> s.length() > 2)
               .forEach(System.out::println);

       
       // now, let's print length of each string using map()
       alphabets.stream()
               .mapToInt(s -> s.length())
               .forEach(System.out::println);
       
       // how about calculating sum of length of all string
       alphabets.stream()
               .mapToInt(s -> s.length())
               .sum();

    }

}



Important things to remember:

1) The forEach() is a terminal operation, which means once calling the forEach() method on stream, you cannot call another method. It will result in a runtime exception.

2) When you call forEach() on a parallel stream, the order of iteration is not guaranteed, but you can ensure that ordering by calling the forEachOrdered() method.

3) There is two forEach() method in Java 8, one defined inside Iterable, and the other inside java.util.stream.Stream class. If the purpose of forEach() is just iteration then you can directly call it like list.forEach() or set.forEach() but if you want to perform some operations like filter or map then it better first get the stream and then perform that operation and finally call forEach() method.

4) Use of forEach() results in readable and cleaner code.

Here are some advantages and benefits of Java 8 forEach() method over traditional for loop:

How to use forEach() method in Java 8? Examples


That's all about how to use forEach() in Java 8. By following these examples, you can easily get to speed with respect to using the forEach() method. It's perfect to be used along with stream and lambda expression, and allow you to write loop-free code in Java. 

Now, one task for you, how do you break from forEach()? Does the forEach() method allow you to break in between? If you know the answer posts it as a comment.


Further Reading
  • Top 10 Java 8 Tutorials for Programmers (read here)
  • 5 good books to learn Java 8 from scratch (see here)
  • 20 Examples of new Date and Time API of JDK 8 (examples)
  • How to read a file in just one line in Java 8? (solution)
  • 10 JDK 7 features to revise before starting with Java 8? (features)
  • Java 8 map + filter + collect tutorial (examples)
  • 5 Free Courses to learn Java 8 and Java 9 (courses)
  • 7 Best Cousess to learn Java Collections and Stream (courses)
  • The Complete Java Developer RoadMap (guide)
  • 10 Examples of Stream in Java 8 (Examples)
  • 10 Examples of Collectors in Java 8 (examples)
  • 10 Courses to become a full-stack Java developer (free courses)

P. S.: If you want to learn more about new features in Java 8 then please see this list of best Java 8 courses on Udemy. It explains all important features of Java 8 e.g. lambda expressions, streams, functional interfaces, Optional, new date, and time API, and other miscellaneous changes.

6 comments:

  1. The best article that explains streams easily.

    ReplyDelete
  2. Doesn’t talk about the most critical part of for each lambda, how to exit the for each.

    ReplyDelete
    Replies
    1. Hello Umang, good point, I will probaby add that infomration when I update this article but for now, you can use the takeWhile method of Java 9 to break from forEach loop in Java like this

      takeWhile(n -> n.length() <=5)

      Delete
  3. So you want to say only usecase of forEach() loop is to do - sytem.out.println . What a waste of time !

    ReplyDelete
    Replies
    1. Why do you think that? because I am not saying that use of forEach() is only limited to printing. If you look syntax, it accept a Consumer interface. I have just use System.out.println() here as an example but you can pass any Consumer functional interface (An interface which take one value but doesn't return anything)

      Delete

Feel free to comment, ask questions if you have any doubt.