The Comparison Of The Different Java ForEach()

Photo by Emile Perron on Unsplash

Back here with me talking about Java again. This time, I would like to talk about the forEach() method that I believe is not unfamiliar anymore for those who know about Java. But, do you know about the different forEach() like the one from Iterable and Stream?

The forEach() method is basically used to loop values, except this is like a shorter short form that makes coding looks neater and simpler in a glance. However, what makes me want to talk about it is because of one occasion when I noticed that two different forEach() from different classes were being used. I remember pondering about it for quite some time and then proceeded to show my team lead about it and asked him why. He briefly mentioned how it doesn’t matter and I can standardize. There was another occasion though, where he mentioned how one does not need to use the forEach() from Stream if you simply want to iterate and nothing more. However, I felt that I needed to find out more about these.

Hence, I decided to take a look further and thought that if you are as curious enough as me, perhaps I can share what I know. After all, we can all learn together to be better together!


Iterable forEach() vs Stream forEach()

The Iterable forEach() can be accessed from the java.lang.Iterable package which you actually don’t need to import. The syntax would be as follow:

list.forEach();

Basically, it directly loops the List called “list” based on the example above. It iterates all the elements inside the list until the end. This is the main difference between this kind of loop and the usual for loop with the variable, condition, etc. How to use it? It will be shown as the example below:

List<Integer> list = Arrays.asList(1,2,3,4);
list.forEach(System.out::println);
// Output
1
2
3
4

Looks pretty simple and does what it means. For each of the elements, I print the element out as per my code above. For those who are not familiar about the double colon operator, the other writing would be as follow:

List<Integer> list = Arrays.asList(1,2,3,4);
list.forEach(el -> System.out.println(el));
// Output
1
2
3
4

For this method, you would need lambda. Otherwise, you would probably use a double colon operator. But the main point is that it directly iterates through the List collection.

Meanwhile, Stream uses what is seemingly the same method, except you need to have stream() before the forEach(). Here is the syntax:

list.stream().forEach();

For a first timer, this probably looks weird but it works almost the same as the one from Iterable. It also iterates all the elements. Let’s take a look at the example:

List<Integer> list = Arrays.asList(1,2,3,4);
list.stream().forEach(System.out::println);
// Output
1
2
3
4

For those who are not familiar with the double colon operator, here is another style:

List<Integer> list = Arrays.asList(1,2,3,4);
list.stream().forEach(el -> System.out.println(el));
// Output
1
2
3
4

Now, both of them do give the same output. However, based on a lot of things that I have read, they mostly produce the same output with the attention especially to the one from Stream. Although, based on my repeated testing and what people have said, that they usually produce the same orderly output.

Now, what’s so interesting about this? What caused the needed extra attention on the forEach() from Stream? The forEach() from Iterable actually iterates elements in the order of iteration that has been specified. This means that you can override the order of iteration. However, the processing order for stream().forEach() is undefined.

Interesting? However, in most cases, it doesn’t really matter which one of the two you pick. It is because in the end they still produce the same results. If you do want to have a certain order for your stream().forEach() iteration, you can perhaps use stream().forEachOrdered() instead. This will ensure it will iterate based on the order.


Parallel Stream forEach() vs Normal Stream forEach()

We have gone through the forEach() for both Iterable and Stream. Now we are going to look at the forEach() for normal Stream and parallel Stream. Iterable does not really have such a thing, hence we are going to compare Stream against Stream instead.

When running forEach() between normal Stream and parallel Stream, the results become obvious whereby the results for parallel Stream are definitely not in order. As it is run in parallel, it doesn’t care when the result is output. As long as it is done, it outputs. Hence, it is not in order. We will see the syntax for parallel Stream:

list.parallelStream().forEach();

Example:

List<Integer> list = Arrays.asList(1,2,3,4);
list.parallelStream().forEach(System.out::println);
// Output
3
4
1
2

You can try it yourself and the output won’t be:

1
2
3
4

This is definitely different from the stream().forEach() way. However, there is one way to make it produce results in order even though it is in parallel. Here it is:

list.parallelStream().forEachOrdered();

Yes, just like the name suggests, it iterates elements in an ordered manner. Let’s take a look at the example:

List<Integer> list = Arrays.asList(1,2,3,4);
list.parallelStream().forEachOrdered(System.out::println);
// Output
1
2
3
4

I have never really used it in that way. Perhaps, one day I would but it is still good and interesting to know the usage.


Wrap-Up

We have seen how the different forEach() methods can be used as well as knowing the differences between the parallel forEach() and non-parallel forEach(). Personally, I have used parallel and non-parallel ones before with the reason of trying to improve the performance usage even a little bit. So when there is no need for procedural, you can use parallelStream() instead. Also, the use of Collection forEach() instead of Stream forEach() is usually preferable if none of the Stream superiority is going to be utilized.

For those who have used these specifically in a more in-depth way, perhaps you can help to provide your opinions in the comment box down below! With that said, if you have any more additions related to these, you can also share them in the comment box down below. Keep learning and grow together!

Thank you for reading.