2012-05-26 7 views
255

Quel est le moyen le plus simple d'inverser cette ArrayList?Quelle est la manière la plus simple d'inverser une ArrayList?

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()); 

Répondre

633
Collections.reverse(aList); 

Exemple (Reference):

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); 
+37

La façon la plus simple. juste une ligne .. –

+2

@AgarwalShankar je reçois une erreur requise ArrayList trouvé void. Est-ce que j'ai raté quelque chose? –

+8

@SagarDevanga La liste est inversée en place, pas retourné. – Carcigenicate

18

pas la façon la plus simple, mais si vous êtes un fan de récursivité vous pourriez être intéressé par la méthode suivante pour inverser une ArrayList:

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

Ou non récursivement:

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; 
} 
+0

Je peux me tromper, mais dans votre exemple non récursif, 'int j' n'est-il pas mis à jour à chaque itération? Vous l'initialisez à 'j = list.size() - 1' mais je ne pense pas que la section _initialization_ de la boucle for soit mise à jour à chaque itération le fait? –

+0

@Turbo j n'a pas besoin d'être mis à jour à chaque itération. Il est initialisé au dernier index de ArrayList et est utilisé pour accéder au dernier élément. A l'intérieur de la boucle for, le dernier élément est supprimé et inséré dans l'index i; i est incrémenté jusqu'à ce qu'il atteigne l'avant-dernière position dans ArrayList. – todd

+1

Oui, mais à la deuxième itération, n'obtiendrez-vous pas une IndexOutOfBoundsException depuis que vous essayez d'accéder à 'j' (le dernier index de l'ArrayList d'origine) mais vous avez déjà supprimé l'objet à cet index? –

0

Un peu plus lisible :)

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; 
} 
4

Solution sans utiliser des méthodes ArrayList supplémentaires ou une combinaison d'add() et remove(). Les deux peuvent avoir un impact négatif si vous devez inverser une liste énorme.

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); 
} 
0

Une autre solution récursive

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

Juste au cas où nous utilisons Java 8, nous pouvons utiliser Stream. L'ArrayList est une liste d'accès aléatoire et nous pouvons obtenir un flux d'éléments dans l'ordre inverse, puis le collecter dans un nouveau ArrayList.

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

L'approche ci-dessus ne convient pas à LinkedList car ce n'est pas un accès aléatoire. Nous pouvons également utiliser instanceof pour vérifier aussi bien.

4

L'astuce ici est de définir "reverse". On peut modifier la liste en place, créer une copie dans l'ordre inverse, ou créer une vue dans l'ordre inverse.

La manière, parlant intuitivement plus simple, est Collections.reverse:

Collections.reverse(myList); 

Cette méthode modifie la liste en place. C'est-à-dire, Collections.reverse prend la liste et écrase ses éléments, ne laissant aucune copie non inversée derrière. Ceci est approprié pour certains cas d'utilisation, mais pas pour d'autres; de plus, il suppose que la liste est modifiable. Si cela est acceptable, nous sommes bons.


Dans le cas contraire, on pourrait créer une copie dans l'ordre inverse:

static <T> List<T> reverse(final List<T> list) { 
    final List<T> result = new ArrayList<>(list); 
    Collections.reverse(result); 
    return result; 
} 

Cette approche fonctionne, mais nécessite itérer sur la liste deux fois. Le constructeur de copie (new ArrayList<>(list)) effectue une itération sur la liste, tout comme Collections.reverse. Nous pouvons réécrire cette méthode pour itérer une seule fois, si nous sommes tellement enclins:

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

Ceci est plus efficace, mais aussi plus bavard.

Alternativement, on peut réécrire ci-dessus pour utiliser l'API Java 8 stream, qui certaines personnes trouver plus concise et lisible que ce qui précède:

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. que Collectors.toList() fait très peu de garanties sur la liste de résultats. Si vous voulez vous assurer que le résultat revient en tant que ArrayList, utilisez plutôt Collectors.toCollection(ArrayList::new).


La troisième option consiste à créer une vue dans l'ordre inverse. C'est une solution plus compliquée, et digne d'une lecture plus approfondie/sa propre question. La méthode Lists#reverse de Guava est un point de départ viable.

Le choix d'une implémentation «la plus simple» est laissé comme un exercice pour le lecteur.

2
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)); 
} 
0

Inverser une ArrayList d'une manière récurrente et sans créer une nouvelle liste pour les éléments en ajoutant:

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

} 
Questions connexes