2017-02-19 2 views
0

Ich habe ein Objekt, das eine Variable hat, die ich in der Lage sein möchte, entweder eine Warteschlange oder einen Stapel zu halten. Alles, was hinzugefügt und entfernt wird mit den entsprechenden Logiken. Ich denke, dass dies mit einer Schnittstelle getan werden kann, aber die beiden in java.util haben nicht die gleiche Schnittstelle oder sogar den gleichen Namen für die beiden Operationen.Wie mache ich eine Variable, die eine Warteschlange oder einen Stapel speichern kann?

Mein Plan ist jetzt, einen Wrapper zu erstellen, damit sie passen, was ich will, aber das scheint unelegant. Gibt es einen besseren Weg?

Ich möchte so etwas wie:

Something<E> steps; 

Damit ich step.pop() aufrufen können und step.push() oder was auch immer Methodennamen ohne wissen zu müssen, wenn Schritte Warteschlangenlogik oder Stapellogik implementiert.

+0

Warum funktionieren 'java.util.Queue ' und 'java.util.Stack ' nicht für Sie? – Moira

+0

Es muss eine einzelne Variable von Something <> sein, die entweder –

Antwort

5

Je nach Bedarf könnten Sie entweder ArrayDeque oder LinkedList möchten.

Beide implementieren Deque (double ended queue).

Aus dem Javadoc on ArrayDeque: "Diese Klasse ist wahrscheinlich schneller als Stack, wenn sie als Stack verwendet wird, und schneller als LinkedList, wenn sie als Warteschlange verwendet wird."

Elemente können an beiden Enden eines Deque hinzugefügt oder entfernt werden.

A Deque kann als eine Warteschlange verwendet werden, indem addLast und removeFirst, aufrufen und auch durch einen Stapel verwendet werden, kann durch addLast und removeLast verwenden.

Wenn Sie es wirklich wie entweder eine verhalten wollen, können Sie eine boolean-Flag halten und Hilfsmethoden schreiben, oder Sie können eine Klasse schreiben:

public class QueueOrStack<E> implements Iterable<E> { 

    private Deque<E> container = new ArrayDeque<E>(); 
    private boolean isQueue; 

    public QueueOrStack(boolean isQueue) { 
     this.isQueue = isQueue; 
    } 

    public E pop() { 
     return isQueue ? container.removeFirst() : container.removeLast(); 
    } 

    public void push(E element) { 
     container.addLast(element); 
    } 

    public void pushAll(E... element) { 
     for (E e : element) 
      container.addLast(e); 
    } 

    public boolean isQueue() { 
     return isQueue; 
    } 

    public void setQueue(boolean isQueue) { 
     this.isQueue = isQueue; 
    } 

    public boolean toggleQueue() { 
     return isQueue = !isQueue; 
    } 

    @Override 
    public Iterator<E> iterator() { 
     return container.iterator(); 
    } 
} 

Hier ist der Test:

QueueOrStack<String> strings = new QueueOrStack<>(true); 
strings.pushAll("hello", ", " , "world\n"); 
for(String s : strings) 
    System.out.print(s); //"hello, world" 
System.out.println(strings.pop()); //"hello" 
strings.toggleQueue(); 
System.out.println(strings.pop()); //"world" 
+0

Ich möchte etwas wie etwas Schritte speichern, wo ich steps.pop() und step.push() aufrufen kann, ohne darüber nachzudenken, ob es eine Warteschlange oder ist ein Stapel. LinkedList scheint, dass Sie eine Auswahl treffen müssen –

+0

@TimothyElbert ['Queue's haben keine' pop' oder 'push' Methoden] (https://docs.oracle.com/javase/7/docs/api/java /util/Queue.html) so oder so, aber Sie könnten Hilfsmethoden oder eine separate Klasse (die Sie in Ihrer Frage erwähnt haben) schreiben. Ich werde meine Antwort bearbeiten. – Moira

+0

@TimothyElbert Bearbeitet. – Moira

Verwandte Themen