2017-02-19 60 views
0

我有一个对象有一个变量,我希望能够保持队列或堆栈。任何有适当的逻辑添加和删除的东西。我认为这可以通过一个界面来完成,但是java.util中的两个界面不具有相同的界面,或者两个操作的界面名称不同。如何创建一个可以存储队列或堆栈的变量?

我现在的计划是创建一个包装,使它们适合我想要的东西,但这看起来不够雅致。有没有更好的办法?

我想是这样的:

Something<E> steps; 

所以,我可以打电话step.pop()和step.push()或任何方法的名称,而不必知道如果步骤实现队列逻辑或栈逻辑。

+0

为什么不'java.util.Queue '和'java.util.Stack '为你工作? – Moira

+0

它必须是Something <>的一个变量,它可以存储 –

回答

5

根据您的需要,您可能需要ArrayDequeLinkedList

两者都执行Deque(双端队列)。

来自Javadoc ArrayDeque:“当用作堆栈时,该类可能比Stack快,并且在用作队列时比LinkedList快。

元素可以从Deque的任一端添加或删除。

Deque可以通过调用addLastremoveFirst用作队列,并且也可以通过堆叠使用addLastremoveLast使用。

如果你真的想表现得像任何一个,你可以保持一个布尔标志,写辅助方法,或者你可以写一个类:

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

这里的测试:

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

我想要某些东西步骤,我可以调用steps.pop()和step.push(),而不必考虑它是否是队列或一个堆栈。 LinkedList似乎需要您做出选择 –

+0

@TimothyElbert ['Queue's没有'pop'或'push'方法](https://docs.oracle.com/javase/7/docs/api/java /util/Queue.html),但您可以编写助手方法或单独的类(在您的问题中提到您)。我将编辑我的答案。 – Moira

+0

@TimothyElbert编辑。 – Moira