Ich migriere einen Code, um Generika zu verwenden. Ein Argument dafür ist, dass die for-Schleife viel sauberer ist als das Verfolgen von Indizes oder die Verwendung eines expliziten Iterators.
In etwa der Hälfte der Fälle wird die Liste (eine ArrayList) heute mithilfe eines Index in umgekehrter Reihenfolge iteriert.
Kann jemand einen saubereren Weg vorschlagen, dies zu tun (da ich das indexed for loop
bei der Arbeit mit Sammlungen nicht mag), obwohl es funktioniert?
for (int i = nodes.size() - 1; i >= 0; i--) {
final Node each = (Node) nodes.get(i);
...
}
Hinweis: Ich kann keine neuen Abhängigkeiten außerhalb des JDK hinzufügen.
java
collections
Allain Lalonde
quelle
quelle
for (int i = nodes.size(); --i >= 0;)
Antworten:
Versuche dies:
quelle
listIterator
Anruf, denke ich.Iterator
, die eineListIterator
Umkehrung verwendet, die sich jedoch für eine Schleife möglicherweise nicht lohnt.for (Node each : new ListReverse<Node>(nodes)) { }
Guave bietet
Lists#reverse(List)
undImmutableList#reverse()
. Wie in den meisten Fällen für Guave delegiert der erstere an den letzteren, wenn das Argument ein istImmutableList
, sodass Sie den ersteren in allen Fällen verwenden können. Diese erstellen keine neuen Kopien der Liste, sondern nur "umgekehrte Ansichten" davon.Beispiel
quelle
Ich denke nicht, dass es möglich ist, die for-Schleifensyntax zu verwenden. Das einzige, was ich vorschlagen kann, ist etwas zu tun wie:
... aber ich würde nicht sagen, dass dies "sauberer" ist, da es weniger effizient sein wird.
quelle
Option 1: Haben Sie darüber nachgedacht, die Liste mit Collections # reverse () umzukehren und dann foreach zu verwenden?
Natürlich möchten Sie Ihren Code möglicherweise auch so umgestalten, dass die Liste korrekt sortiert ist, damit Sie sie nicht umkehren müssen, was zusätzlichen Platz / Zeit beansprucht.
BEARBEITEN:
Option 2: Könnten Sie alternativ eine Deque anstelle einer ArrayList verwenden? Damit können Sie vorwärts und rückwärts iterieren
BEARBEITEN:
Option 3: Wie andere vorgeschlagen haben, können Sie einen Iterator schreiben, der die Liste in umgekehrter Reihenfolge durchläuft. Hier ein Beispiel:
quelle
descendingIterator()
.for each
Ausdrucks ist meiner Meinung nach die idiomatischste Lösung. Es ist schön zu erkennen, dass dies möglich ist, wenn Ihre Liste Iterable so implementiert, dass es rückwärts iteriert. Ich werde diesen Ansatz verwenden und die ReverseListIterator-Klasse aus Apache Commons Collections verwenden.Sie können die konkrete Klasse
LinkedList
anstelle der allgemeinen Schnittstelle verwendenList
. Dann haben Sie einedescendingIterator
zum Iterieren mit der umgekehrten Richtung.Weiß nicht warum es keine gibt
descendingIterator
mitArrayList
...quelle
Dies ist eine alte Frage, aber es fehlt eine Java8-freundliche Antwort. Hier sind einige Möglichkeiten, die Liste mithilfe der Streaming-API rückgängig zu machen:
quelle
Hier ist eine (ungetestete) Implementierung von a
ReverseIterable
. Wenniterator()
es aufgerufen wird, wird eine privateReverseIterator
Implementierung erstellt und zurückgegeben , die einfach AufrufehasNext()
anhasPrevious()
und Aufrufe annext()
zuordnetprevious()
. Dies bedeutet, dass SieArrayList
wie folgt über eine Umkehrung iterieren können :Klassendefinition
quelle
ReverseIterator
es fehlt jedoch der erforderliche Konstruktor und der Code sollteList
stattdessen verwendet werdenArrayList
.Wenn die Listen ziemlich klein sind, so dass die Leistung kein echtes Problem darstellt, kann man das
reverse
-metod derLists
-class in verwendenGoogle Guava
. Ergibt hübschenfor-each
Code und die ursprüngliche Liste bleibt gleich. Außerdem wird die umgekehrte Liste von der ursprünglichen Liste unterstützt, sodass jede Änderung an der ursprünglichen Liste in der umgekehrten Liste berücksichtigt wird.Ergibt folgendes Ergebnis:
Dies bedeutet, dass die umgekehrte Iteration von myList wie folgt geschrieben werden kann:
quelle
Erstellen Sie eine benutzerdefinierte
reverseIterable
.quelle
Sehr einfaches Beispiel:
quelle
Sie können
ReverseListIterator
aus Apache Commons-Collections verwenden:https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/iterators/ReverseListIterator.html
quelle
Auch gefunden Google Sammlungen umgekehrte Methode.
quelle
Um Code zu haben, der so aussieht:
Fügen Sie diesen Code in eine Datei mit dem Namen "In.java" ein:
quelle
listIterator
Feld muss sich innerhalb derIterator
Implementierung befinden, nicht in derIterable
Implementierung.name()
Methode, eineordinal()
Methode und einestatic valueOf()
Methode.Wie mindestens zweimal vorgeschlagen wurde, können Sie
descendingIterator
mit aDeque
, insbesondere mit a, verwendenLinkedList
. Wenn Sie die for-each-Schleife verwenden möchten (dh eine habenIterable
), können Sie einen Wraper wie folgt erstellen und verwenden:quelle
Grund: "Weiß nicht, warum es mit ArrayList keinen absteigenden Iterator gibt ..."
Da die Array-Liste die Liste nicht in derselben Reihenfolge hält, in der Daten zur Liste hinzugefügt wurden. Verwenden Sie also niemals Arraylist.
Die verknüpfte Liste hält die Daten in derselben Reihenfolge wie ADD to list.
Also habe ich oben in meinem Beispiel ArrayList () verwendet, um den Benutzer dazu zu bringen, seinen Verstand zu verdrehen und ihn dazu zu bringen, etwas von seiner Seite zu trainieren.
An Stelle von
VERWENDEN:
quelle