Java 8 - Journey of for loop in Java - for() to forEach() Examples (original) (raw)

for loop has come a long way in Java 8 with a new forEach() method in java.util.stream.Stream class. In this article, we will take a look at the journey of for loop in different versions of the Java programming language. for loop is there from the very beginning of Java i.e. JDK 1.0. Almost all Java programmers have used the classical for() loop, as it is also an essential programming construct, I guess just next to if-else, but when the foreach loop or as some people call it enhanced for loop was introduced in JDK 1.5, everything changed from looping over Collection and array perspective.

Yesterday's popular looping construct becomes old and ugly and a more elegant solution took over. It was shorter, cleaner, and less error-prone, what else did you need at that time.

Things were quiet in terms of for loop from the last 10 years, but In Java 8, looping has taken another big step in its new avatar, forEach() method. It's not only short, clean but also takes advantage of lazy evaluation and inbuilt parallelism of Java 8 Stream. let's revisit this journey of for loop in Java in this post of Javarevisited.

Pre-JDK 1.5, this was my favorite way of iterating over an ArrayList or HashSet :

// pre JDK 1.5, printing each element of List using for loop List countries = Arrays.asList("India", "Australia", "England", "South Africa");

for(int i=0; i < countries.size(); i++){ System.out.println(countries.get(i)); }

So when foreach loop or advanced for loop was added on Java 5, I quickly adapted to the following style of looping over Collection or List :

for(String country : countries){ System.out.println(country); }

This was much shorter, clearer, and less error-prone than the previous one and everybody loved it. You don't need to keep track of the index, you don't need to call size() method in every step and it was less error-prone than the previous one, but it was still imperative. You are telling the compiler what to do and how to do like traditional for loop.

Things change drastically when the functional style of programming was introduced in Java 8 via lambda expression and new Stream API. Now you can loop over your collection without any loop in Java, you just need to use forEach() method of java.util.Stream class, as shown below :

countries.stream().forEach(str -> System.out.println(str));

This code has reduced looping over collection or list into just one line. To add into, If you want to perform some pre-processing task e.g. filtering, conversion or mapping, you can also do this in the same line as shown below :

countries.stream() .filter(country -> country.contains("n")) .forEach(str -> System.out.println(str));

This code will now only print "India" and "England" as it contains the letter "n". Java SE 8 for Really Impatient By Cay S. Horstmann to learn more about filtering in Java 8.

This approach has several advantages over the previous two imperative approaches, first, it segregates what to do from how to do it. You are just telling API to filter the list based upon the condition you have given and then print those elements. Now API can print it by the way it wants, you don't need to worry about it.

The benefit is, you don't need to write imperative code, you will also benefit from lazy evaluation and any performance improvement done by API to accomplish your task. You can even make your code more concise using the method reference feature of Java 8, as shown below :

countries.stream() .filter(country -> country.contains("n")) .forEach(System.out::println);

That "::" or scope resolution operator of C++ is used for method reference since you are not doing anything with String argument of println() then just passing it, you can use method reference there to make your code more clean and concise.

for loop changes in Java 1.4, 5 and 8

Here is the complete code example of using different for loops in Java world, including Java 8 forEach() method. This example demonstrates gradual changes made in for loop from Java 1.4, 5, and Java 8 versions.

package test;

import java.io.IOException; import java.util.Arrays; import java.util.List;

/**

}

So you have seen, for loop has come a long way from JDK 1 to JDK 8, especially when you use with Collection. Gone are the days, when you need to worry about looping index, initializing it properly, making sure it ends properly to avoid IndexOutOfBoundsException, and calling the corresponding to get() method on List.

Java 5 was the first step in making looping over Collection easy but Java 8 has provided a much powerful functional style of looping in Java. In fact, it's not even a loop it's just a method call, which means you can write high-performance Java Collection code without using a loop.

So next time, you need to loop over the collection, just don't use a simple or advanced for loop, considering using the forEach() method of Stream. You will not only benefit from the modern way of filtering and mapping but also from lazy evaluation and performance improvement by smart looping implementation of API itself.

Related Java 8 Tutorials
If you are interested in learning more about the new features of Java 8, here are my earlier articles covering some of the important concepts of Java 8:

Thanks for reading this article so far. If you like this article then please share it with your friends and colleagues. If you have any questions, doubts, or feedback then please drop a comment and I'll try to answer your question.

P.S.: Java 8 is a bundle of many exciting features like this, if you are interested to learn more about them, you can pick any of the these recommend Java 8 books like Java 8 in Action: Lambdas, Streams, and functional-style programming or Mastering Lambdas: Java Programming in a Multicore World.