When to Use Foreach(_:) Instead of for In

Why should I use foreach instead of for (int i=0; i length; i++) in loops?

Two major reasons I can think of are:

1) It abstracts away from the underlying container type. This means, for example, that you don't have to change the code that loops over all the items in the container when you change the container -- you're specifying the goal of "do this for every item in the container", not the means.

2) It eliminates the possibility of off-by-one errors.

In terms of performing an operation on each item in a list, it's intuitive to just say:

for(Item item: lst)
{
op(item);
}

It perfectly expresses the intent to the reader, as opposed to manually doing stuff with iterators. Ditto for searching for items.

Javascript efficiency: 'for' vs 'forEach'

for

for loops are much more efficient. It is a looping construct specifically designed to iterate while a condition is true, at the same time offering a stepping mechanism (generally to increase the iterator). Example:

for (var i=0, n=arr.length; i < n; ++i ) {
...
}

This isn't to suggest that for-loops will always be more efficient, just that JS engines and browsers have optimized them to be so. Over the years there have been compromises as to which looping construct is more efficient (for, while, reduce, reverse-while, etc) -- different browsers and JS engines have their own implementations that offer different methodologies to produce the same results. As browsers further optimize to meet performance demands, theoretically [].forEach could be implemented in such a way that it's faster or comparable to a for.

Benefits:

  • efficient
  • early loop termination (honors break and continue)
  • condition control (i<n can be anything and not bound to an array's size)
  • variable scoping (var i leaves i available after the loop ends)

forEach

.forEach are methods that primarily iterate over arrays (also over other enumerable, such as Map and Set objects). They are newer and provide code that is subjectively easier to read. Example:

[].forEach((val, index)=>{
...
});

Benefits:

  • does not involve variable setup (iterates over each element of the array)
  • functions/arrow-functions scope the variable to the block

    In the example above, val would be a parameter of the newly created function. Thus, any variables called val before the loop, would hold their values after it ends.
  • subjectively more maintainable as it may be easier to identify what the code is doing -- it's iterating over an enumerable; whereas a for-loop could be used for any number of looping schemes

Performance

Performance is a tricky topic, which generally requires some experience when it comes to forethought or approach. In order to determine ahead of time (while developing) how much optimization may be required, a programmer must have a good idea of past experience with the problem case, as well as a good understanding of potential solutions.

Using jQuery in some cases may be too slow at times (an experienced developer may know that), whereas other times may be a non-issue, in which case the library's cross-browser compliance and ease of performing other functions (e.g., AJAX, event-handling) would be worth the development (and maintenance) time saved.

Another example is, if performance and optimization was everything, there would be no other code than machine or assembly. Obviously that isn't the case as there are many different high level and low level languages, each with their own tradeoffs. These tradeoffs include, but are not limited to specialization, development ease and speed, maintenance ease and speed, optimized code, error free code, etc.

Approach

If you don't have a good understanding if something will require optimized code, it's generally a good rule of thumb to write maintainable code first. From there, you can test and pinpoint what needs more attention when it's required.

That said, certain obvious optimizations should be part of general practice and not required any thought. For instance, consider the following loop:

for (var i=0; i < arr.length; ++i ){}

For each iteration of the loop, JavaScript is retrieving the arr.length, a key-lookup costing operations on each cycle. There is no reason why this shouldn't be:

for (var i=0, n=arr.length; i < n; ++i){}

This does the same thing, but only retrieves arr.length once, caching the variable and optimizing your code.

How does the Java 'for each' loop work?

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.

Also, 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.

Java 8 Iterable.forEach() vs foreach loop

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).

Why does Android Studio want me to use For Each instead of For Loop?

From the book: Effective Java (2nd Edition) by Joshua Bloch

The for-each loop, introduced in release 1.5, gets rid of the clutter and the opportunity for error by hiding the iterator or index
variable completely. The resulting idiom applies equally to
collections and arrays:

    // The preferred idiom for iterating over collections and arrays
for (Element e : elements) {
doSomething(e);
}

When you see the colon (:), read it as “in.” Thus, the loop above reads as “for each element e in elements.” Note that there is no
performance penalty for using the for-each loop, even for arrays. In
fact, it may offer a slight performance advantage over an ordinary for
loop in some circumstances, as it computes the limit of the array
index only once. While you can do this by hand (Item 45), programmers
don’t always do so.


Here is a comparison from http://developer.android.com/training/articles/perf-tips.html#Loops:

static class Foo {
int mSplat;
}

Foo[] mArray = ...

public void zero() {
int sum = 0;
for (int i = 0; i < mArray.length; ++i) {
sum += mArray[i].mSplat;
}
}

public void one() {
int sum = 0;
Foo[] localArray = mArray;
int len = localArray.length;

for (int i = 0; i < len; ++i) {
sum += localArray[i].mSplat;
}
}

public void two() {
int sum = 0;
for (Foo a : mArray) {
sum += a.mSplat;
}
}

zero() is slowest, because the JIT can't yet optimize away the cost of
getting the array length once for every iteration through the loop.

one() is faster. It pulls everything out into local variables,
avoiding the lookups. Only the array length offers a performance
benefit.

two() is fastest for devices without a JIT, and indistinguishable from
one() for devices with a JIT. It uses the enhanced for loop syntax
introduced in version 1.5 of the Java programming language.

So, you should use the enhanced for loop by default, but consider a
hand-written counted loop for performance-critical ArrayList
iteration.

Is there a performance difference between a for loop and a for-each loop?

From Item 46 in Effective Java by Joshua Bloch :

The for-each loop, introduced in
release 1.5, gets rid of the clutter
and the opportunity for error by
hiding the iterator or index variable
completely. The resulting idiom
applies equally to collections and
arrays:

// The preferred idiom for iterating over collections and arrays
for (Element e : elements) {
doSomething(e);
}

When you see the colon (:), read it as
“in.” Thus, the loop above reads as
“for each element e in elements.” Note
that there is no performance penalty
for using the for-each loop, even for
arrays. In fact, it may offer a slight
performance advantage over an ordinary
for loop in some circumstances, as it
computes the limit of the array index
only once. While you can do this by
hand (Item 45), programmers don’t
always do so.

What are the advantages of Enhanced for loop and Iterator in Java?

The strengths and also the weaknesses are pretty well summarized in Stephen Colebourne (Joda-Time, JSR-310, etc) Enhanced for each loop iteration control proposal to extend it in Java 7:

FEATURE SUMMARY:

Extends the Java 5 for-each loop to allow access to the
loop index, whether this is the first
or last iteration, and to remove the
current item.

MAJOR ADVANTAGE

The for-each loop is almost certainly the most new
popular feature from Java 5. It works
because it increases the abstraction
level - instead of having to express
the low-level details of how to loop
around a list or array (with an index
or iterator), the developer simply
states that they want to loop and the
language takes care of the rest.
However, all the benefit is lost as
soon as the developer needs to access
the index or to remove an item
.

The original Java 5 for each work took
a relatively conservative stance on a
number of issues aiming to tackle the
80% case. However, loops are such a
common form in coding that the
remaining 20% that was not tackled
represents a significant body of code.

The process of converting the loop
back from the for each to be index or
iterator based is painful. This is
because the old loop style if
significantly lower-level, is more
verbose and less clear
. It is also
painful as most IDEs don't support
this kind of 'de-refactoring'.

MAJOR BENEFIT:

A common coding idiom is expressed at
a higher abstraction than at present.
This aids readability and clarity.

...

To sum up, the enhanced for loop offers a concise higher level syntax to loop over a list or array which improves clarity and readability. However, it misses some parts: allowing to access the index loop or to remove an item.

See also

  • Java 7 - For-each loop control access
  • Stephen Colebourne's original writeup

When to use forEach(_:) instead of for in?

There is no performance benefit offered by forEach. In fact, if you look at the source code, the forEach function actually simply performing for-in. For release builds, the performance overhead of this function over simply using for-in yourself is immaterial, though for debug builds, it results in an observable performance impact.

The main advantage of forEach is realized when you are doing functional programming, you can add it to a chain of functional calls, without having to save the prior result into a separate variable that you'd need if you used for-in syntax. So, instead of:

let objects = array.map { ... }
.filter { ... }

for object in objects {
...
}

You can instead stay within functional programming patterns:

array.map { ... }
.filter { ... }
.forEach { ... }

The result is functional code that is more concise with less syntactic noise.

FWIW, the documentation for Array, Dictionary, and Sequence all remind us of the limitations introduced by forEach, namely:

  1. You cannot use a break or continue statement to exit the current
    call of the body closure or skip subsequent calls.

  2. Using the return statement in the body closure will exit only from
    the current call to body, not from any outer scope, and won't skip
    subsequent calls.

Advantages of std::for_each over for loop

The nice thing with C++11 (previously called C++0x), is that this tiresome debate will be settled.

I mean, no one in their right mind, who wants to iterate over a whole collection, will still use this

for(auto it = collection.begin(); it != collection.end() ; ++it)
{
foo(*it);
}

Or this

for_each(collection.begin(), collection.end(), [](Element& e)
{
foo(e);
});

when the range-based for loop syntax is available:

for(Element& e : collection)
{
foo(e);
}

This kind of syntax has been available in Java and C# for some time now, and actually there are way more foreach loops than classical for loops in every recent Java or C# code I saw.



Related Topics



Leave a reply



Submit