繁体   English   中英

使用Java传递指向链表的指针。 但是,当我修改内存/阵列中的数据时,链表中的数据并未更新。 为什么?

[英]passing pointers to linked list using java. But when I modify the data in the memory/Array it's not updated in the Linked List. Why?

我是JAVA的新手。 我正在尝试制作几个链表。 所有持有指针/对某个数组元素的引用。 因此,如果我对数组进行任何更改,它都应反映在链接列表中。 对? 在我的程序中,修改显示在数组中,但列表值相同。 (我删除了一个元素。它不再在数组中。但是链接列表仍在显示它)

我正在传递对链表的引用。 如果可行,为什么修改不起作用? 看起来链表有自己的数据副本。 但是,那不是参考的工作方式。

有什么解释吗? 建议还有什么可以用来显示内存依赖性?

“(我删除了一个元素。”您不能更改数组的大小。

根据您最可能看到的内容,如果删除了一个元素,则创建了一个新数组,其中元素减少了一个。 这就是为什么LinkedList中的对象似乎未更改的原因。

first.add(WM.get(0))。

当您这样做时,它与

Object referenceToObject = WM.get(0);
first.add(referenceToObject);

// removes the reference from WM.
WM.remove(0);
// this doesn't change referenceToObject or first
assert referenceToObject != null;
assert first.get(first.size() - 1) == referenceToObject;

但是你可以做到

// a reference to a reference.
AtomicReference<String> ref = new AtomicReference<>("Hello");

first.clear();
first.add(ref);

second.clear();
second.add(ref);

// all still there
assert first.get(0).get() == "Hello";
assert second.get(0).get() == "Hello";

// alter ref and all change
ref.set("World");
assert first.get(0).get() == "World";
assert second.get(0).get() == "World";

// or
ref.set(null);
assert first.get(0).get() == null;
assert second.get(0).get() == null;

LinkedList中没有构造函数或方法来指定后备数组。 听起来您有一个数组和一个LinkedList,并且正在向该数组添加一个对象,然后将该对象添加到LinkedList实例。 在这种情况下,从数组中删除对象不会将其从LinkedList中删除。 根据您的描述,您应该将对象添加到LinkedList实例,并将其用作事实的来源。

您的链接列表不包含对“数组元素”的引用,而是对数组引用的对象的引用。

// Create array
Person[] persons = new Person[2];
persons[0] = new Person("A");
persons[1] = new Person("B");

// Create linked list (of persons in reverse order)
LinkedList<Person> list = new LinkedList<>();
list.add(persons[1]);
list.add(persons[0]);

此时, persons (数组)和list都引用了两个对象(人员A和人员B)。 如果将新的引用值分配给数组元素,则仅更新数组,而不更新列表。 但是,它们都引用相同的对象,因此,如果更改对象,它们都会“看到”它。

// Update array
persons[0] = new Person("C");

// Rename person B to B2
persons[1].setName("B2");

// Show content
System.out.println(persons[0] + ", " + persons[1]);
System.out.println(list);

假设Person已实现toString()以返回名称,则这将是您的输出:

C, B2
[B2, A]

我已在上面发表评论,但我认为您的回答值得一个答案。

我使用ArrayListWM = new ArrayList <>制作了数组。 然后我使用WM.add(string)手动输入一些值。 首先创建2个列表,然后使用LinkedList创建第二个列表,然后将指针放置如下:first.add(WM.get(0)),second.add(WM.get(0))。 然后我删除了WM [0]。 表明。 但第一和第二不受影响。

正如我在评论中提到的,Java是按值传递。 碰巧的是,当您传递对象时,会将引用的值传递给该对象。

当您执行first.add(WM.get(0)) ,将发生WM.get(0)得到评估并返回引用的情况。 然后,此引用first.add值传递给first.add因此现在我们对原始对象有两个引用。 现在,当您“删除” WM [0]处的值时,您实际上正在执行的操作是删除对原始对象的一个​​引用。 其他参考保持不变。

我如何才能实现按引用致电? 这样,每个人都会使用/编辑/更新相同的对象/数组元素?

对于使用和更新对象(通过在其上调用方法来改变其状态),您所拥有的一切都很好。 如果通过更新意味着将一个对象的所有引用替换为对另一个对象的引用,那么这与Java的引用系统不符。 引用类似问题的答案; 即使可以,也不要这样做。

最终,您要解决什么问题? 您已经说过您是Java的新手,这可能只是学习惯用的Java方法来解决问题的一种情况,而不是尝试使用您熟悉的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM