Java中的deques队列

时间:2016-01-14 15:50:57

标签: java data-structures

我想要一个符合deques列表的数据结构。因此,利用队列中元素的FIFO处理,我实例化了以下内容:

Deque<String> pathQueue = new ArrayDeque<>();

还有,

Queue<Deque<String>> myQueueOfDeques = new LinkedList<Deque<String>>();

但是,当我添加每个双端队列并打印myQueueOfDeques时,它会显示正确的空字段大小,例如当它应该存储三个deques它显示[ [], [], [] ]。这是代码的一部分。

for (Element leaf; (leaf = (Element)walker.nextNode()) != null; ) {
            for (Node node = leaf; node.getNodeType() == Node.ELEMENT_NODE; node = node.getParentNode())
            {
                pathQueue.addFirst(((Element)node).getAttribute("id"));
            }
            myQueueOfDeques.add(pathQueue);
            pathQueue.clear();
        }
 System.out.println(myQueueOfDeques);

显然问题在于我一直认为它是数据结构在c ++中的工作方式,但是我知道这是java,我很难过。我已经阅读了这里找到的不同结构的文档

1 个答案:

答案 0 :(得分:1)

你需要了解一件重要的事情:在Java中,一切都是引用,引用的行为有点像C ++中的指针。因此,当您向队列添加双端队列时,您不会添加副本,而是添加您刚刚填充的队列。当然,这在性能方面非常好,但最终pathQueue与最小队列中的内容不同,但队列完全相同。然后你清除它,当然它现在是空的。怎么处理?显然,每次都要创建一个新队列。与C ++不同,Java中的分配非常便宜,所以在大多数情况下,你应该更喜欢它一遍又一遍地重复使用同一个对象。

鉴于此,您的代码应该如下所示:

for (Element leaf; (leaf = (Element)walker.nextNode()) != null; ) {
    Deque<String> pathQueue = new ArrayDeque<>();
    for (Node node = leaf; node.getNodeType() == Node.ELEMENT_NODE; node = node.getParentNode())
    {
        pathQueue.addFirst(((Element)node).getAttribute("id"));
    }
    myQueueOfDeques.add(pathQueue);
}
System.out.println(myQueueOfDeques);

正如我所提到的,你应该使用ArrayDeque作为队列。它的时间和内存通常比LinkedList更有效。事实上,我相信,当你真正想要使用LinkedList时,你想要在中间快速插入和删除。否则,ArrayDeque通常对队列和堆栈都更好(有一个名为Stack的类,但它被认为是过时的,所以在查找堆栈时,查找实现Deque接口的任何内容)

所以你应该真正将主队列声明改为:

Queue<Deque<String>> myQueueOfDeques = new ArrayDeque<Deque<String>>();