我想对内存中存在很短时间的对象使用WeakHashMap。
每个对象都有一个id (唯一的整数字段,它是DB的主键),所以我的第一个想法是使用该字段作为对象的键。
但是,Integer是不可变的,所以AFAIK,哈希将产生另一个不可变的整数,因此只要任何其他无关的对象指向它,该对象就不会是GCed。
有没有办法在WeakHashMap中使用整数键?
发布于 2018-07-23 11:43:07
在Integer中使用WeakHashMap键并不会阻止移除键。一旦不存在对放入到Integer中的相同的 Integer实例的引用,则可能会垃圾收集Map密钥。如果对不同的 Integer实例的引用等于(即具有相同的数值)到WeakHashMap中的键,则不会阻止自动删除该键。
请注意,您的WeakHashMap值不能包含对键的强引用,否则该键永远无法自动删除。因此,要避免这种情况,只需向WeakHashMap添加如下值:
Integer key = new Integer(someObject.getID());
weakMap.put(key,someObject);现在,一旦不再保留对由Integer变量引用的key实例的引用,WeakHashMap就可以自动删除它。
如果您不保留对键(即put )的引用,则WeakHashMap中的条目将能够立即自动删除,我认为这不是您想要的。
发布于 2018-07-23 11:42:04
正如您所说,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.
}发布于 2018-07-23 11:54:58
在WeakHashMap中使用Integer作为键的问题之一是,当它映射到的值仍在内存中时,整数可以被垃圾收集。
如果您希望在不妨碍垃圾收集的情况下将这些项作为HashMap中的值,那么您应该将它们包装到一个WeakReference中,并将它们作为一个常规映射Map<Integer, <WeakReference<Item>>中的值使用,也许可以使用一种机制来不时删除未使用的键。
或者,如果不需要从它们的ids中检索它们,则可以将这些项本身用作WeakHashMap的键,并使用Collections#newSetFromMap从它们创建一个集合。
https://stackoverflow.com/questions/51477728
复制相似问题