【问题标题】:Does modifying a copy of the current instance affect the current instance? (Java)修改当前实例的副本会影响当前实例吗? (爪哇)
【发布时间】:2021-04-23 14:55:36
【问题描述】:

昨天我对 Java 中的双向链表有疑问,我的这部分代码有一个令人困惑的注释

public ADList<K,D> split(K key){

// caching the current list
ADList<K, D> temp = this;

// looking for the key k to be split on
while(temp.head.key != key && temp.head.succ != null){
    temp.head = temp.head.succ;
}
...

}

在这里,我保存了调用该方法的双向链表的当前实例,以查找具有传递给函数的键的节点。我这样做是为了不修改当前实例的列表。

但有人告诉我这是错误的,temp 的副本实际上并不是列表的副本,而是指向当前实例列表的指针 的副本。这意味着该函数将更改当前实例而不是副本。

我错了,还是那个人把 Java 和 C 混为一谈了? (大声笑)我真的很感激一些见解 :) 非常感谢!

【问题讨论】:

  • ADList&lt;K,D&gt; temp = this 不会创建对象的副本。所以你没有错。

标签: java c list pointers


【解决方案1】:

您实际上是在将 reference 存储到当前列表中。所以现在对temp 的更改将影响this,并且您的方法将更改原始列表。想一想:

ADList<K, D> temp = this;

存储对列表的引用,而不是列表本身。

同样的事情:

ADList<K, D> list = ...
ADLlist<K, D> temp = list;  // not a copy, both refer to the same list object

如果你想复制,你必须实现自己的机制,例如使用复制构造函数:

ADList<K, D> temp = new ADList<>(this);

构造器会做任何必要的事情来创建一个ADList,并将列表的相同内容传递给它的参数。这可能意味着在内部为每个 Node 创建新的 Node 对象,其中包含相同的数据。

鉴于您要解决的问题,您似乎想在给定键上拆分链表。然后在Node 级别操作要好得多。您可以遍历您的原始列表(即this)而无需修改它。然后为左右子列表创建新节点(参见Divide a linked list into half and return the second half 示例)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-06
    • 1970-01-01
    • 1970-01-01
    • 2011-12-22
    相关资源
    最近更新 更多