【问题标题】:How to get Node-Entry Reference from LinkedList in java如何从 Java 中的 LinkedList 获取节点条目参考
【发布时间】:2021-01-06 03:55:29
【问题描述】:

如何从 LinkedList 获取对实际节点(条目)对象的引用 - 不是它所拥有的值
像这样:

import java.util.LinkedList;

public class Main {

    public static void main(String[] args) {

        LinkedList<String> test = new LinkedList<String>();

        test.addLast("first");
        test.addLast("second");

        test.addLast("third");
        var thirdNodeReference = test.getLastNode(); // Does this even exist ?

        test.addLast("fourth");

        var secondNodeReference = thirdNodeReference.previous(); // To perform such operations.
    }

}

java LinkedList 中是否存在类似LinkedList.getLastNode() 的方法,以便对其执行previous()next() 操作?

我知道LinkedList.listIterator() 存在,但这没有用,因为我将引用每个节点(条目),我需要使用它们 - 例如上面代码中的lastNodeReference

如果 JAVA 标准库中不存在这样的功能,我可以使用任何第三方(外部)库吗?

原因:

我需要访问节点以在O(1) 中执行remove() 操作。

在实际的JAVA code implementation 中,它在O(N) 中执行此操作,方法是遍历列表以通过在其路径上的每个节点上执行equals() 来查找包含给定对象的节点。另外,请检查此comment
如果我们有对 Node 对象的直接引用,这可以在 O(1) 中理想地执行 - 因为 remove() 只需要更改 previousnext Node 的 2 个指针。

【问题讨论】:

  • 您将以何种方式“与他们合作”?也就是说,你想做什么ListIterator 不允许你做?
  • 您无法直接访问Node 条目,它不是LinkedList 的公共api 的一部分,它是内部的东西。见这里:hg.openjdk.java.net/jdk/jdk11/file/1ddf9a99e4ad/src/java.base/…,它被实现为private static class Node&lt;E&gt;
  • @KevinAnderson 所以我需要维护 2 LinkedLists&lt;String&gt;(原始,更新)。假设我有一个对original 列表的中间节点之一的引用:someNode。所以,现在我需要更新它的字符串值 -> 从original 列表中弹出它 -> 将它插入到最后更新的列表中。我突然想到,当我将它从原始列表中弹出时,我必须更新前一个节点的 next 值以指向下一个节点的下一个 someNode
  • @MarcoLucidi 任何具有此类功能的第三方库?
  • 这与仅仅从original删除节点有何不同?您已经可以在 ListIterator 或列表本身上使用 remove() 方法。

标签: java linked-list java-11 doubly-linked-list standard-library


【解决方案1】:

链表可以这样表示:

所以不,您无法使用链表获取前一个元素。 您可能想要实现一个双链表(示例代码可以很容易地在 google 上找到)

【讨论】:

  • JAVA的LinkedList实现为Doubly-Linked List
  • 其实java中的LinkedList实现了Dequeue接口,所以底层肯定有双向链表。但我从没想过访问底层节点。
【解决方案2】:

LinkedList 上有一个descendingIterator 方法,被描述为Returns an iterator over the elements in this deque in reverse sequential order,虽然它不(完全)清楚 OP 想要什么,但 Iterator 确实有一个 .next、.previous 和 .remove 方法。

【讨论】:

  • 我已经修改并在问题中添加了我的原因。让我知道这是否能消除任何困惑
猜你喜欢
  • 1970-01-01
  • 2018-04-17
  • 1970-01-01
  • 2015-06-28
  • 1970-01-01
  • 1970-01-01
  • 2022-07-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多