381 Stimmen

Was ist der einfachste Weg, um eine ArrayList umzukehren?

Was ist der einfachste Weg, diese ArrayList umzukehren?

ArrayList<Integer> aList = new ArrayList<>();

//Add elements to ArrayList object
aList.add("1");
aList.add("2");
aList.add("3");
aList.add("4");
aList.add("5");

while (aList.listIterator().hasPrevious())
  Log.d("reverse", "" + aList.listIterator().previous());

895voto

Shankar Agarwal Punkte 40316
Collections.reverse(aList);

Beispiel ( Referenz ):

ArrayList aList = new ArrayList();
//Add elements to ArrayList object
aList.add("1");
aList.add("2");
aList.add("3");
aList.add("4");
aList.add("5");
Collections.reverse(aList);
System.out.println("After Reverse Order, ArrayList Contains : " + aList);

25voto

naomimyselfandi Punkte 305

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.

22voto

todd Punkte 1246

Nicht die einfachste Methode, aber wenn Sie ein Fan von Rekursionen sind, könnte Sie die folgende Methode interessieren, um eine ArrayList umzukehren:

public ArrayList<Object> reverse(ArrayList<Object> list) {
    if(list.size() > 1) {                   
        Object value = list.remove(0);
        reverse(list);
        list.add(value);
    }
    return list;
}

Oder nicht rekursiv:

public ArrayList<Object> reverse(ArrayList<Object> list) {
    for(int i = 0, j = list.size() - 1; i < j; i++) {
        list.add(i, list.remove(j));
    }
    return list;
}

7voto

Tolunay Guney Punkte 71
ArrayList<Integer> myArray = new ArrayList<Integer>();

myArray.add(1);
myArray.add(2);
myArray.add(3);

int reverseArrayCounter = myArray.size() - 1;

for (int i = reverseArrayCounter; i >= 0; i--) {
    System.out.println(myArray.get(i));
}

6voto

contrapost Punkte 643

Lösung ohne Verwendung einer zusätzlichen ArrayList oder einer Kombination der Methoden add() und remove(). Beides kann negative Auswirkungen haben, wenn Sie eine große Liste umkehren müssen.

 public ArrayList<Object> reverse(ArrayList<Object> list) {

   for (int i = 0; i < list.size() / 2; i++) {
     Object temp = list.get(i);
     list.set(i, list.get(list.size() - i - 1));
     list.set(list.size() - i - 1, temp);
   }

   return list;
 }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X