放入HashMap后更改值会改变HashMap中的内容吗?

Die*_*ego 35 java hashmap pass-by-reference

如果我创建一个新的HashMap和一个新的List,然后用一些任意键将List放在Hashmap中,然后调用List.clear()它会影响我在HashMap中放置的内容吗?

这里更深层次的问题是:当我向HashMap添加内容时,是复制并放置了一个新对象还是对放置的原始对象的引用?

谢谢!

Sco*_*eld 46

这里发生的是你在散列图中放置一个指向列表的指针,而不是列表本身.

当你定义

List<SomeType> list;
Run Code Online (Sandbox Code Playgroud)

您正在定义指向列表的指针,而不是列表本身.

当你这样做

map.put(somekey, list);
Run Code Online (Sandbox Code Playgroud)

你只是存储指针的副本,而不是列表.

如果,在其他地方,您遵循该指针并在其末尾修改对象,那么持有该指针的任何人仍将引用相同的修改对象.

有关Java中的pass-by-value的详细信息,请参阅http://javadude.com/articles/passbyvalue.htm.

  • 当然有.为什么你认为有一个"新"的运营商.请阅读上面引用的文章 - 它将帮助您了解Java真正在做什么.仅仅因为java没有以与C/C++相同的方式实现指针并不意味着它没有指针.Pascal实现了没有算术的指针...... (9认同)
  • 永远不会有足够的链接...(我把它放在上面的答案的评论中b/c他们首先发布 - 很多人不会读过前几个答案,只是简单地投票).程序员可以很好地看到差异 - swap(x,y)和输出/变量参数是一些语言中存在的两个非常重要的语言特性(例如C++,Ada,Pascal),而不是Java. (4认同)
  • 人们看到"参考"并让所有人感到困惑.Sun决定将指针称为"参考值",将"传递参考"传递给人们的头脑. (3认同)
  • @Diego有一些术语问题.但是,如果你看一下被接受的术语,而不是Sun"正式"称之为它们,那么很明显发生了什么.Sun通过使用接受的术语来定义其名称的含义,因为它们明确声明引用*是*指针(JLS 4.3.1). (2认同)

Jam*_*eld 12

Java是按值传递的.

将列表添加到哈希映射只是添加对哈希映射的引用,该哈希映射指向相同的列表.因此,直接清除列表确实会清除您在散列映射中引用的列表.

  • aaaaaaahhhhh!没有!!!!Java严格按值传递!请参阅http://javadude.com/articles/passbyvalue.htm (6认同)
  • 真的,我看不出有什么难以理解的.这是一个非常明显的区别,唯一的问题是Sun决定将指针称为"参考值".他们在JLS中提到引用值是指向实例或数组的指针(4.3.1),并且很明显方法参数存储*值*(4.12.13).因此,Java有指针,并且是按值传递的. (4认同)
  • 它有很大的危害.传递引用语义允许您执行诸如创建交换方法之类的操作(请参阅我在对此答案的第一条评论中引用的文章); 你不能用Java做到这一点. (3认同)
  • 我们知道。Java是按价值传递的。但是,这样说可能会造成混淆。Java的行为就像通过引用传递一样。 (2认同)

dai*_*gio 5

当我向HashMap中添加某些内容时,是复制并放置了新对象还是放置了对原始对象的引用?

它始终是对对象的引用。如果清除HashMap,则该对象仍将处于“活动”状态。如果没有人再引用该对象,则该对象将被垃圾收集器销毁。如果需要复制它,请查看Object.clone()方法和Cloneable接口


Tai*_*aiz 5

Map<Integer, Integer> hasmapA = new HashMap<>();
hasmapA.put("key1", "value1");
hasmapA.put("key2", "value2");
hasmapA.put("key3", "value3");
Run Code Online (Sandbox Code Playgroud)
  1. 通过引用复制:如果将一个HashMap分配给另一个,则两者都指向内存中的同一引用。

    地图有mapB;

    哈希图B = 哈希图A;

如果您对其中任何一个进行更改,更改将反映在两个HashMap中,因为两者都引用相同的位置。

  1. 按值复制:如果您愿意

克隆/深复制/创建单独的内存位置/创建单独的对象

hashmapB 的同时复制 hashmapA 的内容

Map<Integer, Integer> hashmapB = new HashMap<>();;

hashmapB.putAll(hashmapA)
Run Code Online (Sandbox Code Playgroud)

注意: ** 您是否注意到 hashmapB 声明的两点差异?第二点我们必须调用 **HashMap构造函数。这样我们就可以hashmapA的所有数据放入hashmapB中。

参考