HashMap<StringBuilder, StringBuilder> aMap = new
HashMap<StringBuilder, StringBuilder>();
StringBuilder emp = new StringBuilder("Stack");
StringBuilder val = new StringBuilder("Programmer");
aMap.put(emp, val);
emp = new StringBuilder("sss");
System.out.println(aMap);`
尽管
emp
值被更改,但它不会反映在HashMap中。是因为HashMap在放置新值时使用了某种复制构造函数吗?现在来到WeakHashMap:
WeakHashMap<StringBuilder, StringBuilder> aMap1 =
new WeakHashMap<StringBuilder, StringBuilder>();
StringBuilder emp1 = new StringBuilder("WeakStack");
StringBuilder val1 = new StringBuilder("Programmer");
aMap1.put(emp1, val1);
emp1 = new StringBuilder("WeakStack1");
在进行一些GC调用后,
aMap1
变为空。为什么这样?是否因为指向的键不再存在?更新:我从答案中了解到,键是从HashMap引用的,因此,通过在其上附加一个字符串(如
emp
)来更改上述HashMap
中的emp.append("changed")
(可变键)时,它会反映在HashMap
中。 WeakHashMap
也是如此(如果更改/更新了可变键,则会反映出更改)。这意味着正在从WeakHashMap引用该密钥。谁能解释
WeakHashMap
实现的不同之处,即尽管引用了密钥也可以对其进行垃圾回收?谢谢。
最佳答案
emp = new StringBuilder("sss");
不会影响HashMap
中已有的条目(由语句new StringBuilder("Stack");
创建的条目),因为HashMap
包含自己对StringBuilder
实例的引用,该实例最初由。它不会创建emp
实例的副本,而只会保留引用的副本。
另一方面,使用StringBuilder
时,WeakHashMap
中存在键不会阻止对其进行垃圾回收,因此,如果没有其他引用,则您可以将GC释放到映射中该实例。因此,在为WeakHashMap
分配新实例后,只有映射包含对它引用的原始实例的引用,并且GC可以释放它。
这是相关的Javadoc参考:
当WeakHashMap中的项不再是普通使用时,将自动删除该项。更确切地说,给定键的映射的存在不会阻止该键被垃圾收集器丢弃
编辑:
关于emp1
的实现方式有何不同,WeakHashMap
的Entry
扩展了WeakHashMap
,这是一个实例,它引用另一个实例(在此例中为条目的键)并且不会阻止GC释放其参考对象。
关于java - HashMap-更改键值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35893458/