Przeprowadzam migrację fragmentu kodu, aby korzystać z ogólnych. Jednym z argumentów przemawiających za tym jest to, że pętla for jest znacznie bardziej przejrzysta niż śledzenie indeksów lub używanie jawnego iteratora.
W około połowie przypadków lista (ArrayList) jest iterowana w odwrotnej kolejności przy użyciu dzisiaj indeksu.
Czy ktoś może zasugerować bardziej przejrzysty sposób (ponieważ nie lubię indexed for loop
pracy z kolekcjami), chociaż to działa?
for (int i = nodes.size() - 1; i >= 0; i--) {
final Node each = (Node) nodes.get(i);
...
}
Uwaga: Nie mogę dodać żadnych nowych zależności poza JDK.
java
collections
Allain Lalonde
źródło
źródło
for (int i = nodes.size(); --i >= 0;)
Odpowiedzi:
Spróbuj tego:
źródło
listIterator
Myślę, że potrzebujesz indeksu w połączeniu.Iterator
że używaListIterator
odwrotnej strony, ale może to nie być warte jednej pętli.for (Node each : new ListReverse<Node>(nodes)) { }
Oferty Guava
Lists#reverse(List)
iImmutableList#reverse()
. Jak w większości przypadków w przypadku Guawy, ten pierwszy przekazuje go drugiemu, jeśli argumentem jestImmutableList
, więc możesz użyć tego pierwszego we wszystkich przypadkach. Nie tworzą one nowych kopii listy, a jedynie „odwrócone widoki”.Przykład
źródło
Nie sądzę, że jest to możliwe przy użyciu składni pętli for. Jedyne, co mogę zasugerować, to zrobić coś takiego:
... ale nie powiedziałbym, że jest to „czystsze”, biorąc pod uwagę, że będzie mniej wydajne.
źródło
Opcja 1: Czy zastanawiałeś się nad odwróceniem listy za pomocą kolekcji # reverse (), a następnie za pomocą foreach?
Oczywiście możesz również chcieć zmienić kod tak, aby lista była uporządkowana poprawnie, abyś nie musiał jej odwracać, co zużywa więcej miejsca / czasu.
EDYTOWAĆ:
Opcja 2: Alternatywnie, czy możesz użyć Deque zamiast ArrayList? Umożliwi to iterację do przodu i do tyłu
EDYTOWAĆ:
Opcja 3: Jak sugerowali inni, możesz napisać iterator, który przejdzie listę w odwrotnej kolejności, oto przykład:
źródło
descendingIterator()
.for each
Moim zdaniem użycie wyrażenia jest najbardziej idiomatycznym rozwiązaniem. Miło jest zdawać sobie sprawę, że jest to możliwe, jeśli twoja lista implementuje Iterable w sposób, który iteruje wstecz. Mam zamiar użyć tego podejścia i użyć klasy ReverseListIterator z kolekcji Apache Commons.Możesz użyć konkretnej klasy
LinkedList
zamiast ogólnego interfejsuList
. Potem maszdescendingIterator
iterację w odwrotnym kierunku.Nie wiem, dlaczego nie ma
descendingIterator
zArrayList
...źródło
To stare pytanie, ale brakuje w nim odpowiedzi przyjaznej dla java8. Oto kilka sposobów iteracji listy za pomocą interfejsu API przesyłania strumieniowego:
źródło
Oto (nie przetestowana) implementacja
ReverseIterable
. Poiterator()
wywołaniu tworzy i zwraca prywatnąReverseIterator
implementację, która po prostu odwzorowuje połączeniahasNext()
nahasPrevious()
i połączenia nanext()
są mapowaneprevious()
. Oznacza to, że możesz iterowaćArrayList
w odwrotnej kolejności w następujący sposób:Definicja klasy
źródło
ReverseIterator
brakuje w niej niezbędnego konstruktora iList
zamiast tego należy użyć koduArrayList
.Jeśli listy są dość małe, więc wydajność nie jest prawdziwym problemem, można użyć opcji
reverse
-metodLists
klasy-inGoogle Guava
.for-each
Daje całkiem kod, a oryginalna lista pozostaje taka sama. Ponadto lista odwrócona jest wspierana przez listę oryginalną, więc wszelkie zmiany na liście oryginalnej zostaną odzwierciedlone na liście odwróconej.Daje następujący wynik:
Co oznacza, że odwrotną iterację mojej listy można zapisać jako:
źródło
Utwórz niestandardowy
reverseIterable
.źródło
Bardzo prosty przykład:
źródło
Możesz użyć
ReverseListIterator
z Apache Commons-Kolekcje:https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/iterators/ReverseListIterator.html
źródło
Znaleziono także metodę odwrotną do kolekcji Google .
źródło
Aby mieć kod, który wygląda następująco:
Umieść ten kod w pliku o nazwie „In.java”:
źródło
listIterator
pole musi znajdować się wewnątrzIterator
implementacji, a nieIterable
implementacji.name()
metodę,ordinal()
metodę istatic valueOf()
metodę.Jak zasugerowano co najmniej dwa razy, możesz używać
descendingIterator
zDeque
, w szczególności zLinkedList
. Jeśli chcesz użyć pętli dla każdego (tj. Mieć anIterable
), możesz zbudować i użyć otoki w następujący sposób:źródło
Powód: „Nie wiem, dlaczego nie ma malejącego interfejsu z ArrayList ...”
Ponieważ lista tablic nie utrzymuje listy w tej samej kolejności, w jakiej dane zostały dodane do listy. Nigdy nie używaj Arraylist.
Lista połączona utrzyma dane w tej samej kolejności ADD do listy.
Tak więc powyżej w moim przykładzie użyłem ArrayList (), aby zmusić użytkownika do skręcenia umysłu i zmuszenia go do ćwiczenia czegoś ze swojej strony.
Zamiast tego
POSŁUGIWAĆ SIĘ:
źródło