当我们将 a<key,value>
放入 HashMap 时,如果键已经存在于 HashMap 中,则值将被替换。但是,如果一个键的值本身就是一个 HashMap,那么它会被 HashMap 替换吗?
问问题
467 次
3 回答
8
是的,它会被替换。请记住,地图只存储对其他对象的引用。
你把一个 HashMap 的引用放到一个 map 中,这个 map 保存了一个对这个 HashMap 的引用。
如果您使用相同的键放置对另一个 HashMap 的引用,则对第一个放置的 HashMap 的引用将替换为对新 HashMap 的引用。对象的类型无关紧要。它总是以同样的方式工作。
于 2012-12-20T20:29:51.043 回答
1
如果我理解您的要求,您想知道您刚才所说的是否会导致内存泄漏(如果这不是您要问的,请更新您的问题)。
如果你这样做:
Map<?, ?> m = new HashMap<Object, Object>();
m.put(m, m);
然后m
将最终只包含对自身的引用。由于 Java 的 GC 是如何通过对象引用图工作的,并且因为它们使用在 GC 扫描期间跟踪访问过的节点的算法,如果没有维护对 的引用m
,那么m
将被垃圾收集,尽管包含对自身的引用。循环引用在 Java GC 中得到了完美的处理。
如果m
放置在一个字段中(即,不是在方法内声明的局部变量),那么情况就不同了。
- 如果
m
放置在一个static
字段中,那么总会有一个来自 GC 根的引用,这意味着它不会被回收。注意:从static
字段中强烈引用的任何内容都不会被垃圾收集。 - 如果
m
放置在成员字段(非static
)中,则地图不会被垃圾收集,直到包含它的对象被垃圾收集。 - 如果有多个引用 的字段
m
,则m
不会被垃圾收集,直到所有这些引用都是 a) 可以被垃圾收集的对象的一部分或 b) 设置为null
或某个其他值不再引用m
。
TL;DR垃圾收集器可以很好地处理循环对象引用。
旁注:请用信息更新您的问题,不要只是将其作为评论添加到您的问题或其他人的答案中。
于 2012-12-20T21:16:13.730 回答
0
您问题中的措辞有点不透明,但 aHashMap<HashMap, Object>
完全有效(如果有点奇怪)。在这种情况下,如果:
HashMap map = new HashMap<HashMap<String, String>, String>();
HashMap a = new HashMap<String, String>();
HashMap b = new HashMap<String, String>(); //a.equals(b) == true
map.put(a, "foo"); //map.get(a) would now return "foo"
map.put(b, "bar"); //original entry is replaced, map.get(a) would now return "bar"
于 2012-12-20T21:08:35.353 回答