java - Java 中的双端队列

标签 java data-structures

<分区>

我想要一个符合双端队列列表的数据结构。因此,利用队列中元素的 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>>();

关于java - Java 中的双端队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34793849/

相关文章:

java - 我应该使用什么类型的阻塞队列?

java - 在java构造函数中初始化final变量

java - 如何在 double 中将小数点设置为只有 2 位数字?

java - 如何混合来自 DatagramPackets 的多个实时语音音频流?

java - 删除@ManyToMany关系中的引用方实体: JPA

java - 如何使用 SIGKILL Process.destroy() 执行 SIGTERM 在 java 中终止 Linux 进程

java - 尝试在 androidmanifest 中声明类

c++ - 是否可以删除链表中的最后一个节点?

algorithm - 基数树数据结构插入字符串

python - 如何在磁盘上存储一个巨大的马尔可夫链,同时能够在不使用太多 RAM 的情况下查询它?