Der Trick dabei ist die Definition von "rückwärts". Man kann die Liste an Ort und Stelle ändern, eine Kopie in umgekehrter Reihenfolge erstellen oder eine Ansicht in umgekehrter Reihenfolge erstellen.
Der einfachste Weg, intuitiv gesprochen ist Collections.reverse
:
Collections.reverse(myList);
Diese Methode ändert die Liste an Ort und Stelle . Das heißt, Collections.reverse
nimmt die Liste und überschreibt seine Elemente und hinterlässt keine unumgekehrte Kopie. Dies ist für einige Anwendungsfälle geeignet, für andere jedoch nicht; außerdem setzt es voraus, dass die Liste änderbar ist. Wenn dies akzeptabel ist, ist alles in Ordnung.
Wenn nicht, könnte man eine Kopie in umgekehrter Reihenfolge erstellen :
static <T> List<T> reverse(final List<T> list) {
final List<T> result = new ArrayList<>(list);
Collections.reverse(result);
return result;
}
Dieser Ansatz funktioniert, erfordert aber eine doppelte Iteration über die Liste. Der Kopierkonstruktor ( new ArrayList<>(list)
) iteriert über die Liste, und das gilt auch für Collections.reverse
. Wir können diese Methode so umschreiben, dass sie nur einmal wiederholt wird, wenn wir dazu geneigt sind:
static <T> List<T> reverse(final List<T> list) {
final int size = list.size();
final int last = size - 1;
// create a new list, with exactly enough initial capacity to hold the (reversed) list
final List<T> result = new ArrayList<>(size);
// iterate through the list in reverse order and append to the result
for (int i = last; i >= 0; --i) {
final T element = list.get(i);
result.add(element);
}
// result now holds a reversed copy of the original list
return result;
}
Dies ist effizienter, aber auch ausführlicher.
Alternativ können wir das obige Beispiel so umschreiben, dass es die Java 8-Funktionen verwendet stream
API, die einige Leute prägnanter und leserlicher als die oben genannten finden:
static <T> List<T> reverse(final List<T> list) {
final int last = list.size() - 1;
return IntStream.rangeClosed(0, last) // a stream of all valid indexes into the list
.map(i -> (last - i)) // reverse order
.mapToObj(list::get) // map each index to a list element
.collect(Collectors.toList()); // wrap them up in a list
}
nb. dass Collectors.toList()
gibt nur sehr wenige Garantien für die Ergebnisliste. Wenn Sie sicherstellen wollen, dass das Ergebnis als ArrayList zurückkommt, verwenden Sie Collectors.toCollection(ArrayList::new)
stattdessen.
Die dritte Möglichkeit ist eine Ansicht in umgekehrter Reihenfolge erstellen . Dies ist eine kompliziertere Lösung, die weitere Lektüre bzw. eine eigene Frage wert ist. Guave's Listen#Rückwärts Methode ist ein brauchbarer Ansatzpunkt.
Die Wahl einer "einfachsten" Implementierung bleibt dem Leser überlassen.