如果我创建一个新的HashMap和一个新的List,然后将List放入HashMap中并使用任意键,之后调用
更深层次的问题是:当我向HashMap添加内容时,是复制并放置一个新对象还是放置对原始对象的引用?
谢谢!
List.clear()
,这会影响我放入HashMap中的内容吗?更深层次的问题是:当我向HashMap添加内容时,是复制并放置一个新对象还是放置对原始对象的引用?
谢谢!
List.clear()
,这会影响我放入HashMap中的内容吗?这里发生的情况是你将一个列表的指针放在了哈希表中,而不是列表本身。
当你定义:
List<SomeType> list;
你正在定义一个指向列表的指针,而不是列表本身。
当你执行以下操作时
map.put(somekey, list);
你只是存储了指针的副本,而不是列表本身。
如果在其他地方跟随该指针并修改其末尾处的对象,则持有该指针的任何人仍将引用同一已修改的对象。
请参见http://javadude.com/articles/passbyvalue.htm,了解Java中传递值的详细信息。
Java是按值传递引用的。
将列表添加到哈希表中只是将引用添加到哈希表中,指向同一列表。因此,直接清除列表确实会清除您在哈希表中引用的列表。
Map<Integer, Integer> hasmapA = new HashMap<>();
hasmapA.put("key1", "value1");
hasmapA.put("key2", "value2");
hasmapA.put("key3", "value3");
按引用复制:如果您将一个HashMap赋值给另一个,则两者都指向内存中的同一引用。
Map hasmapB;
hashmapB = hashmapA;
如果您更改其中任何一个,更改将反映在两个HashMap中,因为两者都引用同一位置。
克隆/深拷贝/创建单独的内存位置/创建单独的对象
hashmapA的内容并将其复制到hashmapB中
Map<Integer, Integer> hashmapB = new HashMap<>();;
hashmapB.putAll(hashmapA)
注意:** 你有没有注意到HashMapB声明中的两个点之间的不同之处?在第二个点中,我们必须调用HashMap构造函数。这样我们就可以将hashmapA中的所有数据复制到hashmapB中。
试一试
包测试32;通常在Java中,您总是处理引用(除非您使用“new” [1] 显式地创建新对象)。
因此,在映射中存储的是引用而不是完整的对象副本,更改列表也会影响遍历映射时看到的内容。
这是一种特性,而不是错误 :)
[1] 纯粹主义者会包括“clone()”和序列化,但对于大多数Java代码,“new”是获取对象的方法。
new
表达式会被求值为一个引用。 - user102008