2009-08-07 6 views
0

J'ai deux collections - une ArrayList et une Stack. J'utilise la pile car j'avais besoin de fonctionnalités pop/push simples pour ce bit de code. La ArrayList est essentiellement la variable out car c'est une petite section de code dans la fonction. Par conséquent, les variables sont définies comme telles, puis le code est exécuté pour ajouter des éléments à la pile.Méthode la plus efficace pour inverser une pile et l'ajouter à une ArrayList

ArrayList<String> out = new ArrayList<String>(); 

/* other code.. */ 

Stack<String> lineStack = new Stack<String>(); 

/* code that adds stuff to the stack */ 

La question est, maintenant que j'ai une pile entièrement rempli, comment puis-je placer dans le hors ArrayList dans un ordre inverse puis de l'ordre pop.

Ma première pensée en solution était

while(!lineStack.empty()) { 
    out.add(0, lineStack.pop()); 
} 

... qui fonctionne, mais je crains de l'efficacité de l'ajout d'un élément au début de la ArrayList (qui oblige tous les éléments existants doivent changer. c'est une liste chaînée (je crois) .. grosse affaire ... mais toujours un souci). Aussi, je cours ceci à travers une boucle ... peut-être inutilement. Donc, ma deuxième solution qui n'a pas impliqué de boucle (au moins dans mon code, je suis sûr que les appels back end le font). Je sais que je n'ai pas besoin d'allouer la liste, mais il va garder pour un code plus propre. Cependant, je ne suis pas sûr si cela me donnera un gain de performance particulièrement utile. Donc, ma question est la suivante: laquelle de ces options sera probablement la plus efficace pour les ensembles de taille petite à moyenne? S'il y a une solution plus efficace, quelle serait-elle?

+1

Ajout au début de 'ArrayList' est coûteuse; c'est un 'ArrayList' pas un' LinkedList'. L'ajouter au début est 'O (n^2)'. – notnoop

+0

Veuillez noter que 'Stack' est une sous-classe de' Vector' (qui est presque similaire à 'ArrayList'). Une fois déchargé, peut-être que vous pouvez juste comme «Vector» au lieu de copier la liste. – notnoop

+0

C'est ce que je pensais. Il s'avère que je vais juste avec la méthode out.addAll (lineStack). Je n'ai même pas besoin de le transformer en objet liste. Ce sont des frais généraux inutiles. L'itérateur de la Stack jouera la bonne direction en dépit d'être un stack –

Répondre

21

L'ordre de mise en œuvre Iterable<T> de Stack<T> va dans l'ordre que vous voulez de toute façon, vous pouvez simplement utiliser

new ArrayList<String>(stack); 

Voici un exemple bref mais complet:

import java.util.*; 

public class Test 
{ 
    public static void main(String[] args) 
    { 
     Stack<String> stack = new Stack<String>(); 
     stack.push("Bottom"); 
     stack.push("Middle"); 
     stack.push("Top"); 

     List<String> list = new ArrayList<String>(stack); 

     for (String x : list) 
     { 
      System.out.println(x); 
     } 
    } 
} 

Ceci affiche:

Bottom 
Middle 
Top 

(qui est l'ordre inverse de ce que vous auriez si vous les avez sauté).

EDIT: Une autre question - en avez-vous vraiment besoin dans un ArrayList<String> de toute façon? Stack<T> implémente List<T>; quelles sont les caractéristiques spéciales de ArrayList avez-vous besoin? (Je ne dis pas vous ne pas besoin d'eux, juste vérifier!)

+0

Vous avez fait un très bon point! Je ne peux pas réinitialiser le ArrayList (pas garanti pour être vide), mais puisque l'Iterator va me le donner dans le bon ordre, je peux juste out.addAll (lineStack); .. Je ne sais pas pourquoi j'ai pris la peine de le faire dans une liste. * facepalm * Merci! –

+0

+1 impressionnant, au moins par rapport à ma réponse :) – dfa

+0

A l'édition: Aye. Le ArrayList est utilisé ailleurs et fait partie de l'API - Je ne peux pas vraiment le changer :(. –

1

Sous-classe ArrayList et ajoutez une méthode pop et push. Utilisez ceci comme classe Stack.

Lorsque vous êtes prêt, l'assigner à une variable Arraylist et vous êtes prêt

0

en utilisant Stack.toArray est simple:

@Test 
public void stackToList() { 
    Stack<String> stack = new Stack<String>(); 
    stack.push("aaa"); 
    stack.push("bbb"); 
    stack.push("ccc"); 
    List<String> list= Arrays.asList(stack.toArray(new String[0])); 
    Assert.assertEquals(Arrays.asList("aaa", "bbb", "ccc"), list); 
} 
2

Si vous n'avez pas besoin comme un tableau, mais une autre pile fonctionnerait, pourquoi pas:

Stack<String> reversedStack = new Stack<String>(); while (!oldStack.empty()) { reversedStack.push(oldStack.pop()); }

rapide, simple et facile de voir ce qu'il est Faire.

3

Stack est la sous-classe des collections et des collections a reverse method, vous pouvez juste faire -

Stack originalStack = ... 
    Collections.reverse(originalStack); 
+0

Cela fonctionne car 'Stack' implémente' List', pas parce que 'Stack' est' Collection'; Regardez le type de paramètre 'Collections # reverse' – Justin

Questions connexes