it-swarm.com.de

Was ist der einfachste Weg, eine ArrayList umzukehren?

Was ist der einfachste Weg, diese ArrayList rückgängig zu machen?

ArrayList 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());
293
Ishu
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);
713
Shankar Agarwal

Nicht der einfachste Weg, aber wenn Sie ein Rekursionsfan sind, könnten Sie an der folgenden Methode zum Umkehren einer ArrayList interessiert sein:

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;
}
19
todd

Der Trick hier ist das Definieren von "umgekehrt". Man kann die Liste ä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 übernimmt die Liste und überschreibt deren Elemente, ohne dass eine nicht umgedrehte Kopie zurückbleibt. Dies ist für einige Anwendungsfälle geeignet, für andere jedoch nicht. Außerdem wird davon ausgegangen, dass die Liste modifizierbar ist. Wenn das akzeptabel ist, sind wir gut.


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 jedoch ein zweimaliges Durchlaufen der Liste. Der Kopierkonstruktor (new ArrayList<>(list)) durchläuft die Liste und Collections.reverse. Wir können diese Methode so umschreiben, dass sie nur einmal wiederholt wird, wenn wir dazu neigen:

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 umschreiben, um die stream-API von Java 8 zu verwenden, die einige Personen prägnanter und lesbarer als das Obige findet:

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() nur wenige Garantien bezüglich der Ergebnisliste gibt. Wenn Sie sicherstellen möchten, dass das Ergebnis als ArrayList zurückgegeben wird, verwenden Sie stattdessen Collectors.toCollection(ArrayList::new).


Die dritte Option ist Ansicht in umgekehrter Reihenfolge erstellen. Dies ist eine kompliziertere Lösung und verdient eine weiterführende Lektüre/ihre eigene Frage. Guavas Lists # reverse Methode ist ein praktikabler Ausgangspunkt.

Die Wahl einer "einfachsten" Implementierung bleibt dem Leser als Übung überlassen.

10
naomimyselfandi

Lösung ohne zusätzliche ArrayList oder Kombination von add () - und remove () - Methoden. 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;
 }
6
contrapost
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));
}
5
Tolunay Guney

Umkehren einer ArrayList auf rekursive Weise und ohne Erstellen einer neuen Liste zum Hinzufügen von Elementen

   public class ListUtil {

    public static void main(String[] args) {
        ArrayList<String> arrayList = new ArrayList<String>();
        arrayList.add("1");
        arrayList.add("2");
        arrayList.add("3");
        arrayList.add("4");
        arrayList.add("5");
        System.out.println("Reverse Order: " + reverse(arrayList));

    }

    public static <T> List<T> reverse(List<T> arrayList) {
        return reverse(arrayList,0,arrayList.size()-1);
    }
    public static <T> List<T> reverse(List<T> arrayList,int startIndex,int lastIndex) {

        if(startIndex<lastIndex) {
            T t=arrayList.get(lastIndex);
            arrayList.set(lastIndex,arrayList.get(startIndex));
            arrayList.set(startIndex,t);
            startIndex++;
            lastIndex--;
            reverse(arrayList,startIndex,lastIndex);
        }
        return arrayList;
    }

}
2

Dasselbe können wir auch mit Java 8 machen.

public static<T> List<T> reverseList(List<T> list) {
        List<T> reverse = new ArrayList<>(list.size());

        list.stream()
                .collect(Collectors.toCollection(LinkedList::new))
                .descendingIterator()
                .forEachRemaining(reverse::add);

        return reverse;
    }
1
vijayraj34

Für den Fall, dass wir Java 8 verwenden, können wir Stream verwenden. Die ArrayList ist eine Liste mit wahlfreiem Zugriff. Wir können einen Stream von Elementen in umgekehrter Reihenfolge abrufen und dann in einer neuen ArrayList sammeln.

public static void main(String[] args) {
        ArrayList<String> someDummyList = getDummyList();
        System.out.println(someDummyList);
        int size = someDummyList.size() - 1;
        ArrayList<String> someDummyListRev = IntStream.rangeClosed(0,size).mapToObj(i->someDummyList.get(size-i)).collect(Collectors.toCollection(ArrayList::new));
        System.out.println(someDummyListRev);
    }

    private static ArrayList<String> getDummyList() {
        ArrayList dummyList = new ArrayList();
        //Add elements to ArrayList object
        dummyList.add("A");
        dummyList.add("B");
        dummyList.add("C");
        dummyList.add("D");
        return dummyList;
    }

Der obige Ansatz eignet sich nicht für LinkedList, da dies kein Direktzugriff ist. Wir können auch instanceof verwenden, um dies zu überprüfen. 

1
i_am_zero

Eine andere rekursive Lösung

 public static String reverse(ArrayList<Float> list) {
   if (list.size() == 1) {
       return " " +list.get(0);
   }
   else {
       return " "+ list.remove(list.size() - 1) + reverse(list);
   } 
 }
0
dt94

Etwas lesbarer :)

public static <T> ArrayList<T> reverse(ArrayList<T> list) {
    int length = list.size();
    ArrayList<T> result = new ArrayList<T>(length);

    for (int i = length - 1; i >= 0; i--) {
        result.add(list.get(i));
    }

    return result;
}
0
Yas