2015-09-13 19 views
7

To pytanie borykało się ze mną na czas. Dlaczego czasami Android Studio chce, abym używał For Each zamiast For For Loop, ponieważ kiedy używam For Loop, otrzymuję ostrzeżenie, że mógłbym użyć dla każdego z nich (a przy Alt + Enter sugeruje mi autofokus).Dlaczego program Android Studio chce, żebym używał funkcji For Each zamiast For For Loop?

Na przykład załóżmy, mamy ten kod

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

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

dostaję ostrzeżenie

i to poprawkę zaproponowaną przez Android Studio

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

jest to bardziej wydajnych? Jest powód, dla którego powinienem uzyskać ostrzeżenie dla rzeczywistego używania tylko pętli for?

A może lepiej dla pętli lub dla każdego?

Odpowiedz

24

Z książki: Efektywna Java (2nd Edition) przez Joshua Bloch

Instrukcja for-each pętli, pojawiła się w wersji 1.5, pozbywa się bałaganu i możliwość popełnienia błędu przez ukrywanie iterator lub indeks Zmienna całkowicie. Powstały idiom dotyczy w równym stopniu kolekcje i tablice „w”

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

Gdy pojawi się dwukropek (:), czytać go jako Zatem pętla powyżej brzmi „dla każdego elementu E w elementach. "Zauważ, że nie ma kary za wydajność za użycie pętli for, nawet w przypadku tablic. W rzeczywistości, w pewnych okolicznościach, może on oferować niewielką przewagę wydajności nad zwykłą dla pętli , ponieważ oblicza limit tablicy tylko raz. Chociaż możesz to zrobić ręcznie (pozycja 45), programiści nie zawsze to robią.


Oto porównanie z 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() jest najwolniejsza, ponieważ JIT nie można jeszcze zoptymalizować dala koszt coraz długość tablicy raz dla każdej iteracji przez pętlę.

one() jest szybszy. Wyciąga wszystko na zmienne lokalne, unikając wyszukiwania. Tylko długość macierzy zapewnia wydajność.

jest najszybszy dla urządzeń bez JIT i nieodróżnialny od one() dla urządzeń z JIT. Używa ulepszonej składni pętli for wprowadzonej w wersji 1.5 języka programowania Java.

Tak, należy użyć zwiększona do pętli domyślnie, ale uważają odręcznego liczony pętlę pod kątem wydajności krytycznych ArrayList iteracji się.

1

Jest po prostu bardziej czytelny, gdy po prostu wykonujesz iterację bez patrzenia w przód lub w tył. Cóż, jest czytelny, jeśli wybierzesz dobrą nazwę zmiennej (w przeciwieństwie do anArray dla String: D). Trochę bezpieczniej, bo gdybyś był naprawdę głupim programistą, mógłbyś napisać array[2 * i] i rzucić ArrayOutOfBoundsException. Poza tym, uważam za nieco przesadzone, aby poprosić was o refaktoryzację, że ... jest to idiom wspólny w Javie.