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

31,590

Solution 1

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.

Solution 2

It's just more readable when you just iterate without looking ahead or backward. Well, it's readable if you choose a good variable name (unlike anArray for a String :D). It's a bit safer too because if you were a really stupid programmer you could write array[2 * i] and throw an ArrayOutOfBoundsException. Apart from this, I find it a bit exaggerated to ask you to refactor that... this is a common idiom in Java.

Share:
31,590
user1714647
Author by

user1714647

Updated on July 09, 2022

Comments

  • user1714647
    user1714647 almost 2 years

    This question has been struggling me for time. Why sometimes does Android Studio want me to use For Each instead of For Loop, because when I use For Loop, I get a warning that I could be using for each (and with Alt+Enter it suggests me the autofix).

    For example let's suppose we have this code

    String a = "";
    String[] array = {"A","B","C"};
    
    for(int i = 0; i < array.length; i++) {
        a += array[i];
        a += ",";
    }
    

    I get a warning

    and this is the fix suggested by Android Studio

    for (String anArray : array) {
            a += anArray;
            a += ",";
    }
    

    Is it more performant? There's a reason I should get a warning for actually using just for loop?

    Or when it's better for loop or for each?