哈希映射 - 更改键值


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值是 chnaged,但它不会反映在 HashMap 中。是因为 HashMap 在放置新值时使用某种复制构造函数吗?

现在来到弱哈希图:

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 引用的,所以当上面HashMap中的emp(可变键)通过附加一个字符串来更改时,就像emp.append("changed")一样,它会反映在HashMap中。WeakHashMap也是如此(如果更改/更新可变键,则会反映更改)。这意味着该密钥是从WeakHashMap引用的。

谁能解释一下WeakHashMap实现的不同之处,即密钥可以通过引用进行垃圾回收?

谢谢。

emp = new StringBuilder("sss");不会影响HashMap中已有的条目(由语句 new StringBuilder("Stack"); 创建的条目),因为HashMap包含自己对最初由 emp 引用的StringBuilder实例的引用。它不会创建StringBuilder实例的副本,只会保留引用的副本。

另一方面,对于 WeakHashMapWeakHashMap中存在密钥不会阻止它被垃圾回收,因此如果没有其他引用您放入映射中的密钥,GC 可以释放该实例。因此,将新实例分配给 emp1 后,只有映射包含对它引用的原始实例的引用,GC 可以释放它。

以下是相关的Javadoc参考:

当弱哈希图中的条目不再正常使用时,其密钥将自动删除。更准确地说,给定键的映射的存在不会阻止垃圾回收器丢弃该键

编辑:

至于WeakHashMap的实现有何不同,WeakHashMapEntry扩展WeakReference<Object>,这是一个引用另一个实例(在本例中为条目的键)的实例,并且不妨碍其引用被 GC 释放。

相关内容

  • 没有找到相关文章

最新更新