2015-09-13 13 views
7

この質問は、時間のために私を苦労しています。 For Loopを使用すると、私はそれぞれ(そしてAlt + Enterを押すと自動フィックスを提案する)という警告が表示されるので、Forループの代わりにFor Eachを使用することがAndroidのスタジオで時にはなぜ必要なのでしょうか。例えばなぜAndroid StudioはFor Forループの代わりにFor Eachを使用したいのですか?

は、我々はこのコード

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

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

があるとしましょう、私は警告

を取得し、これは、Android Studioの

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

によって提案された修正プログラムは、それがよりパフォーマンスですか?実際にちょうどforループを使用するためにという警告を得るべき理由がありますか?

ループの場合、またはそれぞれに適している場合は、本から

答えて

24

:リリース1.5で導入されたジョシュアブロッホ効果的なJavaの(第2版)

ザ・について、各ループは、イテレータやインデックスを非表示にすることで、混乱やエラーの機会を取り除きます は完全に可変です。あなたは、コロン(:)は、としてそれを読み取る参照場合

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

したがって、上記ループが各要素eのため」として読み込む:得られたイディオムは コレクションおよびアレイに等しく適用される「です。」配列内であってもfor-eachループを使用する場合には、 のパフォーマンス上のペナルティはありません。 実際には、配列 のインデックスを1回だけ計算するため、状況によっては ループに対して通常よりわずかなパフォーマンス上の利点があります。手でこれを行うことはできますが(Item 45)、プログラマ は必ずしもそうとは限りません。ここで


http://developer.android.com/training/articles/perf-tips.html#Loopsからの比較である:JITはまだすべての反復のため のコストが一度配列の長さを取得離れて最適化することはできませんので

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()は、最も遅いですループを介して。

one()が高速です。ルックアップを避けるために、すべてをローカル変数に引き出します。 配列の長さだけがパフォーマンスを提供します 利点。

two()は、JITのないデバイスでは最も高速で、JITがあるデバイスの場合は one()と区別できません。これは、Javaプログラミング言語のバージョン1.5で導入された拡張forループ構文 を使用します。

したがって、デフォルトで拡張forループを使用する必要がありますが、パフォーマンス重視のArrayList 反復では、 手書きのカウントループを考慮する必要があります。

1

先読みや逆戻りを繰り返さずに反復するだけで読みやすくなります。あなたが良い変数名を選択した場合、それは可読です(String:Dの場合はanArrayと異なります)。あなたが本当に愚かなプログラマーであれば、array[2 * i]と書くことができ、ArrayOutOfBoundsExceptionを投げることができるので、もう少し安全です。これ以外にも、リファクタリングを依頼するのは少し誇張されていますが、これはJavaの共通のイディオムです。

関連する問題