The better practice is to use for-each. Besides violating the Keep It Simple, Stupid principle, the new-fangled forEach() has at least the following deficiencies:

  • Can't use non-final variables. So, code like the following can't be turned into a forEach lambda:
Object prev = null;
for(Object curr : list)
{
    if( prev != null )
        foo(prev, curr);
    prev = curr;
}
  • Can't handle checked exceptions. Lambdas aren't actually forbidden from throwing checked exceptions, but common functional interfaces like Consumer don't declare any. Therefore, any code that throws checked exceptions must wrap them in try-catch or Throwables.propagate(). But even if you do that, it's not always clear what happens to the thrown exception. It could get swallowed somewhere in the guts of forEach()

  • Limited flow-control. A return in a lambda equals a continue in a for-each, but there is no equivalent to a break. It's also difficult to do things like return values, short circuit, or set flags (which would have alleviated things a bit, if it wasn't a violation of the no non-final variables rule). "This is not just an optimization, but critical when you consider that some sequences (like reading the lines in a file) may have side-effects, or you may have an infinite sequence."

  • Might execute in parallel, which is a horrible, horrible thing for all but the 0.1% of your code that needs to be optimized. Any parallel code has to be thought through (even if it doesn't use locks, volatiles, and other particularly nasty aspects of traditional multi-threaded execution). Any bug will be tough to find.

  • Might hurt performance, because the JIT can't optimize forEach()+lambda to the same extent as plain loops, especially now that lambdas are new. By "optimization" I do not mean the overhead of calling lambdas (which is small), but to the sophisticated analysis and transformation that the modern JIT compiler performs on running code.

  • If you do need parallelism, it is probably much faster and not much more difficult to use an ExecutorService. Streams are both automagical (read: don't know much about your problem) and use a specialized (read: inefficient for the general case) parallelization strategy (fork-join recursive decomposition).

  • Makes debugging more confusing, because of the nested call hierarchy and, god forbid, parallel execution. The debugger may have issues displaying variables from the surrounding code, and things like step-through may not work as expected.

  • Streams in general are more difficult to code, read, and debug. Actually, this is true of complex "fluent" APIs in general. The combination of complex single statements, heavy use of generics, and lack of intermediate variables conspire to produce confusing error messages and frustrate debugging. Instead of "this method doesn't have an overload for type X" you get an error message closer to "somewhere you messed up the types, but we don't know where or how." Similarly, you can't step through and examine things in a debugger as easily as when the code is broken into multiple statements, and intermediate values are saved to variables. Finally, reading the code and understanding the types and behavior at each stage of execution may be non-trivial.

  • Sticks out like a sore thumb. The Java language already has the for-each statement. Why replace it with a function call? Why encourage hiding side-effects somewhere in expressions? Why encourage unwieldy one-liners? Mixing regular for-each and new forEach willy-nilly is bad style. Code should speak in idioms (patterns that are quick to comprehend due to their repetition), and the fewer idioms are used the clearer the code is and less time is spent deciding which idiom to use (a big time-drain for perfectionists like myself!).

As you can see, I'm not a big fan of the forEach() except in cases when it makes sense.

Particularly offensive to me is the fact that Stream does not implement Iterable (despite actually having method iterator) and cannot be used in a for-each, only with a forEach(). I recommend casting Streams into Iterables with (Iterable<T>)stream::iterator. A better alternative is to use StreamEx which fixes a number of Stream API problems, including implementing Iterable.

That said, forEach() is useful for the following:

  • Atomically iterating over a synchronized list. Prior to this, a list generated with Collections.synchronizedList() was atomic with respect to things like get or set, but was not thread-safe when iterating.

  • Parallel execution (using an appropriate parallel stream). This saves you a few lines of code vs using an ExecutorService, if your problem matches the performance assumptions built into Streams and Spliterators.

  • Specific containers which, like the synchronized list, benefit from being in control of iteration (although this is largely theoretical unless people can bring up more examples)

  • Calling a single function more cleanly by using forEach() and a method reference argument (ie, list.forEach (obj::someMethod)). However, keep in mind the points on checked exceptions, more difficult debugging, and reducing the number of idioms you use when writing code.

Articles I used for reference:

  • Everything about Java 8
  • Iteration Inside and Out (as pointed out by another poster)

EDIT: Looks like some of the original proposals for lambdas (such as http://www.javac.info/closures-v06a.html Google Cache) solved some of the issues I mentioned (while adding their own complications, of course).

Answer from Aleksandr Dubinsky on Stack Overflow
🌐
W3Schools
w3schools.com › java › java_foreach_loop.asp
Java For-Each Loop
Java Examples Java Videos Java ... ... There is also a "for-each" loop, which is used exclusively to loop through elements in an array (or other data structures):...
🌐
GeeksforGeeks
geeksforgeeks.org › java › for-each-loop-in-java
For-Each Loop in Java - GeeksforGeeks
3 weeks ago - The for-each loop in Java (introduced in Java 5) provides a simple, readable way to iterate over arrays and collections without using indexes.
Discussions

[Java] Simple explanation of for each loops
Alright, so a forEach loop is simply some syntactical sugar. Something that makes a common problem or action easier to do. Easier can mean easier in terms of writing it, but also relates to code readability. Anyways, so a normal for loop takes the three conditions that you have stated: for(int i = 0; i < condition; i++ ) { } So I will have a counter here. A super common thing to use a for loop for, is to loop through the contents of an array. So: for(int i = 0; i < myArray.length; i++) { myElement = myArray[i]; } So, at the i-th index, get the element there, and then let's do something with it. But that's a lot of boilerplate ( read: Lot of typing to do something so basic and common ). So, the solution is to use the forEach loop. So we use the syntax: for ( myObject object : myArray ) { } This seems confusing at first, but break it down. All it is saying, in English is: I would like to loop through every element of myArray. During each loop, I would like the current element I am at to be referenced with the variable object which is of type myObject You are now allowed to work with this. But myObject and object are placeholders, and they aren't the easiest to understand. So I will write you a small program that will sum all of the numbers in an array. int integerArray[] = {5, 10, 15, 20, 25, 30} // With normal for loop int count = 0; for( int i = 0; i < integerArray.length; i++){ int currentInteger = integerArray[i]; count += currentInteger; } // Now, with a for each loop int count = 0; for ( int currentInteger : integerArray ) { count += currentInteger; } Notice, we skipped a step in the second one because it will loop through with the first element of the array as the name currentInteger, and when it is done adding itself to count, it will go to the next element. We don't keep track of the size, we don't have the count variable, we don't have int i or i++, we simply manipulate the elements located within the array and do what we want. Now, of course under the hood Java is keeping track of where we are, and setting that variable to the next one on each rotation, but that's what syntactical sugar is all about. We focus on writing code, not boilerplate, and having a for each loop let's us worry about the actual logic, not correctly initializing a for loop and keeping track of indices. More on reddit.com
🌐 r/learnprogramming
7
1
November 2, 2015
Java 8 Iterable.forEach() vs foreach loop - Stack Overflow
I began to deeply appreciate this ... C# to Java. 2014-04-23T16:07:19.61Z+00:00 ... That's a bad argument. You could use it to justify anything you want: why you shouldn't use a for loop, because a while loop is good enough and that's one less idiom. Heck, why use any loop, switch, or try/catch statement when goto can do all of that and more. 2014-11-18T14:24:04.297Z+00:00 ... forEach() can be implemented to be faster than for-each loop, because ... More on stackoverflow.com
🌐 stackoverflow.com
java - How do I apply the for-each loop to every character in a String? - Stack Overflow
So I want to iterate for each character in a string. So I thought: for (char c : "xyz") but I get a compiler error: MyClass.java:20: foreach not applicable to expression type How can I do this? More on stackoverflow.com
🌐 stackoverflow.com
object - Java: For-Each loop and references - Stack Overflow
I am wondering if the following loop creates a copy of the object, rather than giving me a reference to it. The reason is, because the first example doesn't allocate my array objects, but the secon... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Oracle
docs.oracle.com › javase › 8 › docs › technotes › guides › language › foreach.html
The For-Each Loop
1 week ago - Here is how the example looks with the for-each construct: void cancelAll(Collection<TimerTask> c) { for (TimerTask t : c) t.cancel(); } When you see the colon (:) read it as "in." The loop above reads as "for each TimerTask t in c." As you can see, the for-each construct combines beautifully with generics.
🌐
Reddit
reddit.com › r/learnprogramming › [java] simple explanation of for each loops
r/learnprogramming on Reddit: [Java] Simple explanation of for each loops
November 2, 2015 -

Hi, every example I see of for each loops I see confuses me. I know for for loops it is: for(begining counter; do while counter is less, greater or equal to n; increase or decrease counter) . I was hoping someone could help explain how for each loops work and there applications instead of for loops. Sorry if this is a basic question, other answers I found in the java documentation and on stackoverflow didn't seem to help me.

Edit: I understand now! Thank you guys so much!

Top answer
1 of 2
2
Alright, so a forEach loop is simply some syntactical sugar. Something that makes a common problem or action easier to do. Easier can mean easier in terms of writing it, but also relates to code readability. Anyways, so a normal for loop takes the three conditions that you have stated: for(int i = 0; i < condition; i++ ) { } So I will have a counter here. A super common thing to use a for loop for, is to loop through the contents of an array. So: for(int i = 0; i < myArray.length; i++) { myElement = myArray[i]; } So, at the i-th index, get the element there, and then let's do something with it. But that's a lot of boilerplate ( read: Lot of typing to do something so basic and common ). So, the solution is to use the forEach loop. So we use the syntax: for ( myObject object : myArray ) { } This seems confusing at first, but break it down. All it is saying, in English is: I would like to loop through every element of myArray. During each loop, I would like the current element I am at to be referenced with the variable object which is of type myObject You are now allowed to work with this. But myObject and object are placeholders, and they aren't the easiest to understand. So I will write you a small program that will sum all of the numbers in an array. int integerArray[] = {5, 10, 15, 20, 25, 30} // With normal for loop int count = 0; for( int i = 0; i < integerArray.length; i++){ int currentInteger = integerArray[i]; count += currentInteger; } // Now, with a for each loop int count = 0; for ( int currentInteger : integerArray ) { count += currentInteger; } Notice, we skipped a step in the second one because it will loop through with the first element of the array as the name currentInteger, and when it is done adding itself to count, it will go to the next element. We don't keep track of the size, we don't have the count variable, we don't have int i or i++, we simply manipulate the elements located within the array and do what we want. Now, of course under the hood Java is keeping track of where we are, and setting that variable to the next one on each rotation, but that's what syntactical sugar is all about. We focus on writing code, not boilerplate, and having a for each loop let's us worry about the actual logic, not correctly initializing a for loop and keeping track of indices.
2 of 2
1
Say you have an array of things. Let's call it int[] myArray and let's say we put 1, 2, 3 inside of it. And you want to print each thing inside of myArray. So we start at the beginning of myArray and start walking towards the end. Each step we take, we take the number at that step, set it to some variable i and then print i. You could write a foreach loop like this: for (int i : myArray) { System.out.println(i); } What this does is it goes through myArray, starting at the beginning, and it: Sets i to the current element inside of myArray. Does the stuff in the body (the system.out.print...) So it basically does the stuff in the body for each thing inside of the array. First, i is equal to 1, and it prints 1. Then, i is equal to 2, and it prints 2. Finally, i is equal to 3, and it prints 3.
Top answer
1 of 8
653

The better practice is to use for-each. Besides violating the Keep It Simple, Stupid principle, the new-fangled forEach() has at least the following deficiencies:

  • Can't use non-final variables. So, code like the following can't be turned into a forEach lambda:
Object prev = null;
for(Object curr : list)
{
    if( prev != null )
        foo(prev, curr);
    prev = curr;
}
  • Can't handle checked exceptions. Lambdas aren't actually forbidden from throwing checked exceptions, but common functional interfaces like Consumer don't declare any. Therefore, any code that throws checked exceptions must wrap them in try-catch or Throwables.propagate(). But even if you do that, it's not always clear what happens to the thrown exception. It could get swallowed somewhere in the guts of forEach()

  • Limited flow-control. A return in a lambda equals a continue in a for-each, but there is no equivalent to a break. It's also difficult to do things like return values, short circuit, or set flags (which would have alleviated things a bit, if it wasn't a violation of the no non-final variables rule). "This is not just an optimization, but critical when you consider that some sequences (like reading the lines in a file) may have side-effects, or you may have an infinite sequence."

  • Might execute in parallel, which is a horrible, horrible thing for all but the 0.1% of your code that needs to be optimized. Any parallel code has to be thought through (even if it doesn't use locks, volatiles, and other particularly nasty aspects of traditional multi-threaded execution). Any bug will be tough to find.

  • Might hurt performance, because the JIT can't optimize forEach()+lambda to the same extent as plain loops, especially now that lambdas are new. By "optimization" I do not mean the overhead of calling lambdas (which is small), but to the sophisticated analysis and transformation that the modern JIT compiler performs on running code.

  • If you do need parallelism, it is probably much faster and not much more difficult to use an ExecutorService. Streams are both automagical (read: don't know much about your problem) and use a specialized (read: inefficient for the general case) parallelization strategy (fork-join recursive decomposition).

  • Makes debugging more confusing, because of the nested call hierarchy and, god forbid, parallel execution. The debugger may have issues displaying variables from the surrounding code, and things like step-through may not work as expected.

  • Streams in general are more difficult to code, read, and debug. Actually, this is true of complex "fluent" APIs in general. The combination of complex single statements, heavy use of generics, and lack of intermediate variables conspire to produce confusing error messages and frustrate debugging. Instead of "this method doesn't have an overload for type X" you get an error message closer to "somewhere you messed up the types, but we don't know where or how." Similarly, you can't step through and examine things in a debugger as easily as when the code is broken into multiple statements, and intermediate values are saved to variables. Finally, reading the code and understanding the types and behavior at each stage of execution may be non-trivial.

  • Sticks out like a sore thumb. The Java language already has the for-each statement. Why replace it with a function call? Why encourage hiding side-effects somewhere in expressions? Why encourage unwieldy one-liners? Mixing regular for-each and new forEach willy-nilly is bad style. Code should speak in idioms (patterns that are quick to comprehend due to their repetition), and the fewer idioms are used the clearer the code is and less time is spent deciding which idiom to use (a big time-drain for perfectionists like myself!).

As you can see, I'm not a big fan of the forEach() except in cases when it makes sense.

Particularly offensive to me is the fact that Stream does not implement Iterable (despite actually having method iterator) and cannot be used in a for-each, only with a forEach(). I recommend casting Streams into Iterables with (Iterable<T>)stream::iterator. A better alternative is to use StreamEx which fixes a number of Stream API problems, including implementing Iterable.

That said, forEach() is useful for the following:

  • Atomically iterating over a synchronized list. Prior to this, a list generated with Collections.synchronizedList() was atomic with respect to things like get or set, but was not thread-safe when iterating.

  • Parallel execution (using an appropriate parallel stream). This saves you a few lines of code vs using an ExecutorService, if your problem matches the performance assumptions built into Streams and Spliterators.

  • Specific containers which, like the synchronized list, benefit from being in control of iteration (although this is largely theoretical unless people can bring up more examples)

  • Calling a single function more cleanly by using forEach() and a method reference argument (ie, list.forEach (obj::someMethod)). However, keep in mind the points on checked exceptions, more difficult debugging, and reducing the number of idioms you use when writing code.

Articles I used for reference:

  • Everything about Java 8
  • Iteration Inside and Out (as pointed out by another poster)

EDIT: Looks like some of the original proposals for lambdas (such as http://www.javac.info/closures-v06a.html Google Cache) solved some of the issues I mentioned (while adding their own complications, of course).

2 of 8
174

The advantage comes into account when the operations can be executed in parallel. (See http://java.dzone.com/articles/devoxx-2012-java-8-lambda-and - the section about internal and external iteration)

  • The main advantage from my point of view is that the implementation of what is to be done within the loop can be defined without having to decide if it will be executed in parallel or sequential

  • If you want your loop to be executed in parallel you could simply write

     joins.parallelStream().forEach(join -> mIrc.join(mSession, join));
    

    You will have to write some extra code for thread handling etc.

Note: For my answer I assumed joins implementing the java.util.Stream interface. If joins implements only the java.util.Iterable interface this is no longer true.

Find elsewhere
🌐
Programiz
programiz.com › java-programming › enhanced-for-loop
Java for-each Loop (With Examples)
In Java, the for-each loop is used to iterate through elements of arrays and collections (like ArrayList).
🌐
Baeldung
baeldung.com › home › java › core java › guide to the java foreach loop
Guide to the Java forEach Loop | Baeldung
June 17, 2025 - This interface has a new API starting with Java 8: ... Simply put, the Javadoc of forEach states that it “performs the given action for each element of the Iterable until all elements have been processed or the action throws an exception.”
Top answer
1 of 7
15

Java works a little bit different than many other languages. What o is in the first example is simply a reference to the object.

When you say o = new MyObject(), it creates a new Object of type MyObject and references o to that object, whereas before o referenced objects[index].

That is, objects[index] itself is just a reference to another object in memory. So in order to set objects[index] to a new MyObject, you need to change where objects[index] points to, which can only be done by using objects[index].

Image: (my terrible paint skills :D)

Explanation: This is roughly how Java memory management works. Not exactly, by any means, but roughly. You have objects, which references A1. When you access the objects array, you start from the beginning reference point (A1), and move forward X blocks. For example, referencing index 1 would bring you to B1. B1 then tells you that you're looking for the object at A2. A2 tells you that it has a field located at C2. C2 is an integer, a basic data type. The search is done.

o does not reference A1 or B1, but C1 or C2. When you say new ..., it will create a new object and put o there (for example, in slot A3). It will not affect A1 or B1.

Let me know if I can clear things up a little.

2 of 7
10

The short answer: yes, there is something like a copy going on.

The long answer: The Java foreach loop you posted is syntactic sugar for

MyObject objects[] = new MyObject[6];

Iterator<MyObject> it = objects.iterator();
while (it.hasNext()) {
   MyObject o = it.next();
   // The previous three lines were from the foreach loop

   // Your code inside the foreach loop
   o = new MyObject();
}

As the desugared version shows, setting a reference equal to something inside a foreach loop does not change the contents of the array.

🌐
Runestone Academy
runestone.academy › ns › books › published › csjava › Unit7-Arrays › topic-7-3-arrays-with-foreach.html
7.3. Enhanced For-Loop (For-Each) for Arrays — CS Java
To set up a for-each loop, use for (type variable : arrayname) where the type is the type for elements in the array, and read it as “for each variable value in arrayname”. for (type item: array) { //statements using item; } See the examples below in Java that loop through an int and a String ...
Top answer
1 of 16
1310
for (Iterator<String> i = someIterable.iterator(); i.hasNext();) {
    String item = i.next();
    System.out.println(item);
}

Note that if you need to use i.remove(); in your loop, or access the actual iterator in some way, you cannot use the for ( : ) idiom, since the actual iterator is merely inferred.

As was noted by Denis Bueno, this code works for any object that implements the Iterable interface.

If the right-hand side of the for (:) idiom is an array rather than an Iterable object, the internal code uses an int index counter and checks against array.length instead. See the Java Language Specification.

for (int i = 0; i < someArray.length; i++) {
    String item = someArray[i];
    System.out.println(item);
}
2 of 16
559

The construct for each is also valid for arrays. e.g.

String[] fruits = new String[] { "Orange", "Apple", "Pear", "Strawberry" };

for (String fruit : fruits) {
    // fruit is an element of the `fruits` array.
}

which is essentially equivalent of

for (int i = 0; i < fruits.length; i++) {
    String fruit = fruits[i];
    // fruit is an element of the `fruits` array.
}

So, overall summary:
[nsayer] The following is the longer form of what is happening:

for(Iterator<String> i = someList.iterator(); i.hasNext(); ) {
  String item = i.next();
  System.out.println(item);
}

Note that if you need to use i.remove(); in your loop, or access the actual iterator in some way, you cannot use the for( : ) idiom, since the actual Iterator is merely inferred.

[Denis Bueno]

It's implied by nsayer's answer, but it's worth noting that the OP's for(..) syntax will work when "someList" is anything that implements java.lang.Iterable -- it doesn't have to be a list, or some collection from java.util. Even your own types, therefore, can be used with this syntax.

🌐
Tutorialspoint
tutorialspoint.com › java › java_foreach_loop.htm
Java - for each Loop
Then using foreach loop, each number is printed. import java.util.Arrays; import java.util.List; public class Test { public static void main(String args[]) { List<Integer> numbers = Arrays.asList(10, 20, 30, 40, 50); for(Integer x : numbers ) { System.out.print( x ); System.out.print(","); } } }
🌐
CodeGym
codegym.cc › java blog › loops in java › for each loop in java
For Each Loop in Java
December 26, 2024 - A for-each is a kind of for loop that you use when you need to process all the elements of an array or collection in Java. That said, the phrase for-each is not actually used in this loop.
🌐
TutorOcean
tutorocean.com › questions-answers › can-someone-please-explain-the-difference-between-a-for-loop-and-a-for-each-loop
Can someone please explain the difference between a for ...
Sorry, your browser does not support JavaScript! If possible, please enable JavaScript on your browser or switch to another browser (Chrome, Firefox, Safari) · ‌ ‌ ‌ ‌ ‌ · ‌ ‌ ‌ ‌
🌐
Zero To Mastery
zerotomastery.io › blog › enhanced-for-loop-java
How To Use Enhanced For Loops In Java (aka 'foreach') | Zero To Mastery
January 26, 2024 - Always improving, Java 5 introduced the enhanced for loop as a part of its syntax enrichment. The enhanced for loop, otherwise known as a foreach loop, offers a simplified way to iterate over collections and arrays.
Top answer
1 of 4
4

The Java Language Specification shows the underlying compilation

Let L1 ... Lm be the (possibly empty) sequence of labels immediately preceding the enhanced for statement.

The enhanced for statement is equivalent to a basic for statement of the form:

T[] #a = Expression;
L1: L2: ... Lm:
for (int #i = 0; #i < #a.length; #i++) {
    {VariableModifier} TargetType Identifier = #a[#i];
    Statement
}

where Expression is the right hand side of the : in an enhanced for statement (your returnArr()). In both cases, it gets evaluated only once: in version 1, as part of the enhanced for statement; in version 2, because its result is assigned to a variable which is then used in the enhanced for statement.

2 of 4
1

I'm not going to copy paste from the Java Language Specification, like one of the previous answers did, but instead interpret the specification in a readable format.

Consider the following code:

for (T x : expr) {
    // do something with x
}

If expr evaluates to an array type like in your case, the language specification states that the resulting bytecode will be the same as:

T[] arr = expr;
for (int i = 0; i < arr.length; i++) {
    T x = arr[i];
    // do something with x
}

The difference only is that the variables arr and i will not be visible to your code - or the debugger, unfortunately. That's why for development, the second version might be more useful: You have the return value stored in a variable accessible by the debugger.

In your first version expr is simply the function call, while in the second version you declare another variable and assign the result of the function call to that, then use that variable as expr. I'd expect them to exhibit no measurable difference in performance, as that additional variable assignment in the second version should be optimized away by the JIT compiler, unless you also use it elsewhere.

🌐
IONOS
ionos.com › digital guide › websites › web development › java for-each loop
How to use for-each loops in Java - IONOS
November 3, 2023 - In each iteration, you can perform automatic ma­nip­u­la­tions with common Java operators without having to write a separate statement for each element. In contrast to the for loop in Java, when you use the for-each Java loop, you don’t need to consider the index or size of the array.
🌐
Runestone Academy
runestone.academy › ns › books › published › apcsareview › ArrayBasics › aForEach.html
8.2. Looping with the For-Each Loop — AP CSA Java Review - Obsolete
A for-each loop is a loop that can only be used on a collection of items. It will loop through the collection and each time through the loop it will use the next item from the collection. It starts with the first item in the array (the one at index 0) and continues through in order to the last ...
🌐
Sentry
sentry.io › sentry answers › java › java for-each loops
Java for-each loops | Sentry
December 15, 2023 - This allows us to use the same for-each loop syntax for both arrays and iterables. import java.util.ArrayList; import java.util.List; import java.util.Arrays; class Main { public static void main(String[] args) { List<String> productsList = new ArrayList<>(); productsList.add("Coffee"); productsList.add("Tea"); productsList.add("Chocolate Bar"); String[] productsArray = new String[]{"Coffee", "Tea", "Chocolate Bar"}; for (String product : productsList) { System.out.println(product); } for (String product : productsArray) { System.out.println(product); } // both for loops will produce the same output } }
🌐
Baeldung
baeldung.com › home › java › core java › the for-each loop in java
The for-each Loop in Java | Baeldung
January 8, 2024 - In this tutorial, we’ll discuss the for-each loop in Java along with its syntax, working, and code examples.