我想使用WeakHashMap
将在内存中短时间存在的对象。
每个对象都有一个 id(唯一的整数字段,它是 DB 的主键),所以我的第一个想法是使用该字段作为对象的键。
但是,Integer 是不可变的,因此 AFAIK,哈希将产生另一个不可变的 Integer,因此只要任何其他不相关的对象指向它,该对象就不会被 GC。
有没有办法在 a 中使用整数键WeakHashMap
?
我想使用WeakHashMap
将在内存中短时间存在的对象。
每个对象都有一个 id(唯一的整数字段,它是 DB 的主键),所以我的第一个想法是使用该字段作为对象的键。
但是,Integer 是不可变的,因此 AFAIK,哈希将产生另一个不可变的 Integer,因此只要任何其他不相关的对象指向它,该对象就不会被 GC。
有没有办法在 a 中使用整数键WeakHashMap
?
在 a 中使用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
则将能够立即自动删除它,我认为这不是您想要的。
正如您所说, 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.
}
使用 Integer 作为 WeakHashMap 中的键的问题之一是 Integer 可以被垃圾收集,而它映射到的值仍在内存中使用。
如果您想要将项目作为 HashMap 中的值而不防止它们被垃圾收集,那么您应该将它们包装到 WeakReference 中并将它们用作常规 map 中的值Map<Integer, <WeakReference<Item>>
,也许使用一种机制来删除未使用的键不时。
或者,如果不需要从它们的 id 中检索它们,您可以使用 Items 本身作为 WeakHashMap 的键,并使用Collections#newSetFromMap从它们创建一个集合