我想要一个符合双端队列列表的数据结构。因此,利用队列中元素的 FIFO 处理方式,我实例化了以下内容:
Deque<String> pathQueue = new ArrayDeque<>();
还有,
Queue<Deque<String>> myQueueOfDeques = new LinkedList<Deque<String>>();
但是,当我添加每个双端队列并打印 myQueueOfDeques
时,它会显示正确大小的空字段,例如当它应该存储三个双端队列时,它显示 [ [], [], [] ]
。这是代码的一部分。
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,我很难过。我已经阅读了此处找到的不同结构的文档
您需要了解一件重要的事情:在 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
的类,但它被认为已过时,因此在查找堆栈时,查找任何实现 code>Deque
接口(interface))。
所以你真的应该把你的主队列声明改成这样:
Queue<Deque<String>> myQueueOfDeques = new ArrayDeque<Deque<String>>();