如果我创建一个新的HashMap和一个新的List,然后用一些任意键将List放在Hashmap中,然后调用List.clear()
它会影响我在HashMap中放置的内容吗?
这里更深层次的问题是:当我向HashMap添加内容时,是复制并放置了一个新对象还是对放置的原始对象的引用?
谢谢!
答案 0 :(得分:44)
这里发生的是你将指针放在hashmap中的列表中,而不是列表本身。
定义时
List<SomeType> list;
您正在定义指向列表的指针,而不是列表本身。
当你这样做时
map.put(somekey, list);
你只是存储指针的副本,而不是列表。
如果在其他地方,你遵循该指针并在其末尾修改对象,那么持有该指针的任何人仍将引用相同的修改对象。
有关Java中传递值的详细信息,请参阅http://javadude.com/articles/passbyvalue.htm。
答案 1 :(得分:11)
Java是按值传递的。
将列表添加到哈希映射只会添加对哈希映射的引用,该哈希映射指向相同的列表。因此,直接清除列表确实会清除您在散列映射中引用的列表。
答案 2 :(得分:3)
当我向HashMap添加内容时,是 复制和放置的新对象或是 引用原始对象 放置?
始终是对象的引用。 如果清除HashMap,对象仍将是“实时”。 然后,如果没有人再引用它,该对象将被垃圾收集器销毁。 如果需要复制它,请查看Object.clone()方法和Cloneable接口
答案 3 :(得分:2)
Map<Integer, Integer> hasmapA = new HashMap<>();
hasmapA.put("key1", "value1");
hasmapA.put("key2", "value2");
hasmapA.put("key3", "value3");
按引用复制:如果您将一个 HashMap 分配给其他人,则两者都指向内存中的相同引用。
映射hasmapB;
hashmapB = hashmapA;
如果您对其中任何一项进行了更改,则更改将反映在 HashMap 中,因为两者都引用了相同的位置。
复制hashmapA的内容时,hashmapB的clone / deepcopy /创建单独的内存位置/创建单独的对象
Map<Integer, Integer> hashmapB = new HashMap<>();;
hashmapB.putAll(hashmapA)
注意:** 您是否注意到hashmapB声明的两个点的差异?在第二点,我们必须调用** HashMap 构造函数。这样我们就可以将hashmapA的 putAll 数据放入hashmapB。
答案 4 :(得分:1)
通常你总是在Java中处理引用(除非你用“new”[1]自己明确地创建一个新对象。)
因此,它是一个参考,而不是您存储在地图中的完整对象副本,更改列表也会影响您在浏览地图时看到的内容。
这是一个功能,而不是一个错误:)
[1]清教徒将包括“clone()”和序列化,但对于大多数java代码,“new”是获取对象的方式。
答案 5 :(得分:1)
试一试
package test32; import java.util.ArrayList; import java.util.HashMap; import java.util.List; class Foo { public Foo(int id, String name) { this.id=id; this.name=name; } public static void main(String[] args) { HashMap strs = new HashMap(); // create a list of objects List ls = new ArrayList(); ls.add(new Foo(1, "Stavros")); ls.add(new Foo(2, "Makis")); ls.add(new Foo(3, "Teo")); ls.add(new Foo(4, "Jim")); // copy references of objects from list to hashmap strs.put("1", ls.get(0)); strs.put("2", ls.get(1)); strs.put("3", ls.get(2)); strs.put("4", ls.get(3)); System.out.println("list before change : " + ls); System.out.println("map before change: " + strs); // get an object from the hashmap Foo f=strs.get("1"); // set a different value f.setId(5); // observe that the differences are reflected to the list and to the hashmap also System.out.println("list after change : "+ls); System.out.println("map after change: "+strs); } private int id; public void setId(int id) { this.id=id; } public int getId() { return this.id; } private String name; public void setName(String name) { this.name=name; } public String getName() { return this.name; } public String toString() { StringBuilder sb = new StringBuilder(); sb.append(id); sb.append("-"); sb.append(name); return sb.toString(); } }
答案 6 :(得分:1)
对此的正确答案解释如下: 假设您有一个名为hashmap的HashMap,并且最初在此HashMap中放置一个键值对,例如散列映射&LT; “测试1”, “test2的” 取代。 在此之后,当您将此hashmap传递给一个函数,在该函数中,您再次将其值更改为test3,如hashmap.put(“test1”,“test3”)并再次在main方法中打印映射,此时Java Pass by Value Concept将失败。 / p>
原因是: 当您使用HashMap时,它会为密钥(test1)执行散列并存储该值。当您将它传递给它再次更改其值的函数时,它再次对同一个键执行散列并获取相同的内存地址并更改值。 这就是为什么当你试图检索关键字“test1”时它给你的结果为“test3”
答案 7 :(得分:-2)
Geeze people ...... Java中的一切都是通过价值传递的。传递对象时,传递的值是对象引用。具体来说,您传递的是对象引用的副本。 Java中也没有指针,尽管引用类似。做对了!