Dzisiaj szczęśliwie kodowałem, gdy dotarłem do fragmentu kodu, którego użyłem już setki razy:
Iterowanie po kolekcji (tutaj ArrayList)
Z jakiegoś powodu przyjrzałem się opcjom autouzupełniania Eclipse i zacząłem się zastanawiać:
W jakich przypadkach poniższe pętle są lepsze w użyciu niż inne?
Klasyczna pętla indeksu tablicy:
for (int i = 0; i < collection.length; i++) {
type array_element = collection.get(index);
}
Iterator hasNext () / next ():
for (Iterator iterator = collection.iterator(); iterator.hasNext();) {
type type = (type) iterator.next();
}
I mój ulubiony, ponieważ jest tak prosty do napisania:
for (iterable_type iterable_element : collection) {
}
java
collections
for-loop
Jason Rogers
źródło
źródło
for (Iterator<type> iterator = collection.iterator(); iterator.hasNext();) { type type = iterator.next(); }
Odpowiedzi:
Pierwsza jest przydatna, gdy potrzebujesz również indeksu elementu. Jest to w zasadzie równoważne z pozostałymi dwoma wariantami dla
ArrayList
s, ale będzie bardzo powolne, jeśli użyjesz plikuLinkedList
.Drugi jest przydatny, gdy nie potrzebujesz indeksu elementu, ale może być konieczne usunięcie elementów podczas iteracji. Ale ma to tę wadę, że jest trochę zbyt rozwlekłe w IMO.
Trzecia wersja jest również moim ulubionym wyborem. Jest krótki i działa we wszystkich przypadkach, w których nie potrzebujesz żadnych indeksów ani bazowego iteratora (tj. Uzyskujesz dostęp tylko do elementów, nie usuwając ich ani nie modyfikując
Collection
w jakikolwiek sposób - co jest najczęstszym przypadkiem).źródło
Collection
są tanie w wyszukiwaniu według indeksu).List
zaimplementowano jako drzewo, w rzeczywistości byłoby wolniejsze).Wszystkie mają tam swoje zastosowania:
Jeśli masz element iterowalny i musisz bezwarunkowo przejść przez wszystkie z nich:
for (iterable_type iterable_element: collection)
Jeśli masz iterowalny, ale musisz warunkowo przejść:
for (Iterator iterator = collection.iterator (); iterator.hasNext ();)
Jeśli struktura danych nie implementuje iterowalnej:
for (int i = 0; i <collection.length; i ++)
źródło
break
i / lubcontinue
Istnieje dodatkowo funkcja stream () kolekcji w Javie 8
lub
Więcej informacji o strumieniu Java 8 i linku do kolekcji cudów
źródło
Żaden z nich nie jest „lepszy” od pozostałych. Trzeci jest dla mnie bardziej czytelny, ale dla kogoś, kto nie korzysta z przesłuchań, może wyglądać dziwnie (może wolałby pierwszy). Wszystkie 3 są dość jasne dla każdego, kto rozumie język Java, więc wybierz tę, która sprawi, że poczujesz się lepiej z kodem.
Pierwszy jest najbardziej podstawowy, więc jest to najbardziej uniwersalny wzorzec (działa dla tablic, wszystkich iteracji, jakie przychodzą mi do głowy). To jedyna różnica, jaką przychodzi mi do głowy. W bardziej skomplikowanych przypadkach (np. Trzeba mieć dostęp do bieżącego indeksu lub przefiltrować listę), odpowiednio pierwszy i drugi przypadek mogą mieć większy sens. Dla prostego przypadku (obiekt iterowalny, bez specjalnych wymagań) trzeci wydaje się najczystszy.
źródło
Pierwsza opcja jest lepsza pod względem wydajności (ponieważ ArrayList implementuje interfejs RandomAccess). Zgodnie z dokumentacją java, implementacja List powinna implementować interfejs RandomAccess, jeśli dla typowych instancji klasy pętla:
działa szybciej niż ta pętla:
Mam nadzieję, że to pomoże. Pierwsza opcja byłaby wolna dla sekwencyjnych list dostępu.
źródło
Oto przykład
źródło