我想要一个符合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,我很难过。我已经阅读了这里找到的不同结构的文档
答案 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>>();