我想对在内存中存在很短时间的对象使用WeakHashMap
。
每个对象都有一个id(唯一整数字段,它是数据库中的主键),所以我的第一个念头是使用该字段作为对象的键。
但是,Integer是不可变的,因此AFAIK哈希将生成另一个不可变的Integer,因此只要任何其他不相关的对象指向该对象,该对象就不会被GC化。
是否可以在WeakHashMap
中使用整数键?
答案 0 :(得分:3)
在Integer
中使用WeakHashMap
键不会阻止键被删除。
一旦没有对放置在Integer
中的相同 Integer
实例的引用,就可以对Map
键进行垃圾回收。如果存在对不同 Integer
个实例的引用与WeakHashMap
中的某个键相等(即具有相同的数值),则不会阻止该键被自动删除
请注意,您的WeakHashMap
的值不能持有对该键的强引用-否则,该键永远不会被自动删除。因此,为避免这种情况,只需将值添加到WeakHashMap
中,如下所示:
Integer key = new Integer(someObject.getID());
weakMap.put(key,someObject);
现在,一旦不再保留对Integer
变量所引用的key
实例的引用,WeakHashMap
将可以自由地自动删除它。
如果您在put
中WeakHashMap
中的条目没有保留对键(即weakMap.put(new Integer(someObject.getID()),someObject)
)的引用,则WeakHashMap
将能够立即自动将其删除,我认为这不是您想要的。
答案 1 :(得分:1)
如您所说,WeakHashMap将无法提供所需的功能。 JavaDocs声明以下内容
因此应注意确保值对象不 直接或间接强烈引用自己的键, 因为这样可以防止密钥被丢弃。
因此,您可以实现“ WeakValueMap”。但这并不像听起来那样复杂。您只需将WeakReference包装在类型定义中
Map<Integer, WeakReference<YourType>> cache ...
或者您可以围绕它实现包装器实现。
public class Cache<K, V> implements Map<K, V> {
private final Map<K, V> store = new HashMap<>();
// implement put, get, etc.
}
答案 2 :(得分:0)
使用Integer作为WeakHashMap中的键的问题之一是,可以将Integer进行垃圾回收,而将其映射的值仍在内存中使用。
如果您想要的是将这些项目作为HashMap中的值,而又不阻止它们被垃圾回收,那么您应该将它们包装到WeakReference中,并在常规映射Map<Integer, <WeakReference<Item>>
中将其用作值,也许具有不时删除未使用密钥的机制。
或者,如果不需要从其ID中检索它们,则可以将Items本身用作WeakHashMap的键,并使用Collections#newSetFromMap
从其中创建一个集