2015-09-13 436 views
7

這個問題一直在困擾着我。爲什麼有時候Android Studio會讓我使用For Each而不是For循環,因爲當我使用For循環時,我得到一個警告,我可以爲每個使用(並且使用Alt + Enter它表明我使用了自動修復)。爲什麼Android Studio要我使用For Each而不是For Loop?

例如,讓我們假設我們有這樣的代碼

String a = ""; 
String[] array = {"A","B","C"}; 

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

我得到

,這是修復由Android工作室

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

是不是更好的性能提出了一個警告?有一個原因,我應該得到一個警告實際上只用於循環?

或者當它更好的循環或每個?

回答

24

從書:有效的Java(第2版)由Joshua布洛赫

的for-each循環,在1.5版推出,擺脫雜亂和隱藏迭代器或索引錯誤的機會完全變量爲 。將所得成語同樣適用於 集合和數組:「在」

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

當看到冒號(:),它讀作因此,循環以上讀作「對每個要素e in elements。「請注意,使用for-each循環時不存在 的性能損失,即使對於數組也是如此。在 事實上,在某些情況下,它可能比普通的循環提供輕微的性能優勢,因爲它僅計算一次索引數組 的限制。雖然你可以手工完成(項目45),程序員 並不總是這樣做。


這裏是從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()是最慢的,因爲JIT還不能優化掉的 成本得到數組長度一次每次迭代通過循環。

one()更快。它將所有內容拉入局部變量中,避免查找。只有陣列長度提供了性能 的好處。

two()對於沒有JIT的設備是最快的,並且對於具有JIT的設備沒有區別於 one()。它使用Java編程語言1.5版中引入的增強for循環語法 。

因此,默認情況下應該使用增強的for循環,但考慮使用手寫計數循環進行性能至關重要的迭代ArrayList 。

1

只是在不向前看或向後迭代時它更具可讀性。那麼,如果你選擇一個好的變量名,它就是可讀的(不同於anArrayString:D)。這更安全一點,因爲如果你是一個非常愚蠢的程序員,你可以寫array[2 * i]並拋出一個ArrayOutOfBoundsException。除此之外,我覺得有點誇張地要求你重構一下......這是Java中常見的習慣用法。