2009-08-07 6 views
0

Ich habe zwei Sammlungen - eine ArrayList und einen Stack. Ich benutze den Stack, weil ich ein paar einfache Pop/Push-Funktionen für diesen Code benötigt habe. Die ArrayList ist im Wesentlichen die out-Variable, da dies ein kleiner Codeabschnitt in der Funktion ist.Der effizienteste Weg, einen Stack umzukehren und zu einer ArrayList hinzuzufügen

So werden die Variablen als solche definiert, dann wird Code ausgeführt Elemente zu dem Stapel hinzuzufügen.

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

/* other code.. */ 

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

/* code that adds stuff to the stack */ 

Die Frage ist jetzt, dass ich ein voll bestücktes Stapel haben, wie ich es in der aus Arraylist in umgekehrter Reihenfolge dann aus dem Pop Auftrag vergeben haben.

Mein erster Gedanke up-Lösung war

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

... das funktioniert, aber ich mache mir Sorgen um die Effizienz zu Beginn des Arraylist ein Element der Zugabe (die alle vorhandenen Elemente zwingt, müssen zu verschieben. Es ist eine verknüpfte Liste (glaube ich) .. große Sache .. aber immer noch ein Anliegen). Außerdem führe ich das durch eine Schleife ... vielleicht unnötig.

meine zweite Lösung also, die nicht beinhalten looping (zumindest in meinem Code, ich bin sicher, dass die Back-End-Anrufe es tun).

List l = lineStack.subList(0, lineStack.size()); 
out.addAll(l); 

Ich weiß, dass ich die Liste nicht zuordnen muss, aber es wird für saubereren Code behalten. Ich bin mir jedoch nicht sicher, ob mir das einen besonders nützlichen Leistungsgewinn bringt.

Also, meine Frage ist: Welche davon wird mittlere Größe Sätze wahrscheinlich am effizientesten für SMALL zu? Wenn es eine effizientere Lösung gibt, welche wäre es?

+1

zum Anfang Hinzufügen von 'ArrayList' ist teuer; Es ist eine 'ArrayList' und keine' LinkedList'. Hinzufügen zum Anfang ist "O (n^2)". – notnoop

+0

Bitte beachten Sie, dass 'Stack' eine Unterklasse von' Vector' ist (die der 'ArrayList' ähnelt). Während entladen, vielleicht können Sie es einfach als "Vector", anstatt die Liste zu kopieren. – notnoop

+0

Das habe ich mir gedacht. Stellt sich heraus, ich gehe nur mit der out.addAll (lineStack) -Methode. Ich muss es nicht einmal in ein Listenobjekt verwandeln. Das ist unnötiger Aufwand. Der Iterator des Stacks wird die richtige Richtung spielen, obwohl er ein Stack ist. –

Antwort

21

Die Iterable<T> Implementierung Reihenfolge der Stack<T> geht in der gewünschten Reihenfolge so wie man will, so kann man einfach

new ArrayList<String>(stack); 

verwenden hier ist ein kurzes, aber vollständiges Beispiel:

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

Dies gibt:

Bottom 
Middle 
Top 

(die das Gegenteil ist, um auf das, was Sie bekommen würden, wenn man sie knallte).

EDIT: Eine andere Frage - Sie braucht es in einem ArrayList<String> wirklich überhaupt? Stack<T> implementiert List<T>; Welche Besonderheiten benötigen Sie von ArrayList? (Ich sage nicht, Sie nicht brauchen sie, nur zu überprüfen!)

+0

Du hast einen sehr guten Punkt gemacht! Ich kann die ArrayList nicht reinitialisieren (nicht garantiert, leer zu sein), aber da der Iterator es mir in der richtigen Reihenfolge geben wird, kann ich einfach out.addAll (lineStack); .. Ich weiß nicht, warum ich mich darum gekümmert habe, es zu einer Liste zu machen. * facepalm * Danke! –

+0

+1 genial, zumindest im Vergleich zu meiner Antwort :) – dfa

+0

Zum Bearbeiten: Aye. Die ArrayList wird an anderer Stelle verwendet und ist Teil der API - kann nicht wirklich geändert werden :(. –

1

Subclass der Arraylist und ein Pop und Push-Methode hinzufügen. Verwenden Sie dies als Stack-Klasse.

Wenn Sie bereit sind, weisen sie zu einer Arraylist Variable und Sie sind bereit

0

Verwendung von Stack.toArray ist einfach:

@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

Wenn Sie es als ein Array nicht brauchen, aber ein anderer Stapel funktionieren würde, warum nicht:

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

Schnell, einfach und leicht zu sehen, was es tun.

3

Stack ist Unterklasse von Sammlungen und Sammlungen hat reverse method, also können Sie tun, nur -

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

Das funktioniert, weil 'Stack'' List' implementiert, nicht weil 'Stack' eine' Collection' ist; Betrachte den Parametertyp auf 'Collections # reverse' – Justin