Java Weak Hash Map - Need to remove entry based on weakness of value, not key

只谈情不闲聊 提交于 2019-12-05 05:24:47

Such a map is supported, for example, in Guava:

Map<..., ...> m = new MapMaker().weakValues().makeMap();

The API has the answer:

Implementation note: The value objects in a WeakHashMap are held by ordinary strong references. Thus care should be taken to ensure that value objects do not strongly refer to their own keys, either directly or indirectly, since that will prevent the keys from being discarded. Note that a value object may refer indirectly to its key via the WeakHashMap itself; that is, a value object may strongly refer to some other key object whose associated value object, in turn, strongly refers to the key of the first value object. One way to deal with this is to wrap values themselves within WeakReferences before inserting, as in: m.put(key, new WeakReference(value)), and then unwrapping upon each get.

Why do you want the entry to be garbage collected ? I see two reasons

  1. avoid memory leaks (avoid to keep a weakReference pointing to nothing in your Map)
  2. myMap.get(myKey) should return null if the object was garbage collected.

Solution use a regular HashMap:

Map<String, WeakReference<Object>>

then if 2) is the sole problem just use myMap.get(myKey).get()

If you need to also remove the entries have a look at this post that describes a softHashMap and adapt it to use weakReferences...

You can do what WeakHashMap does, but to values instead of keys: wrap your values in WeakReferences, and associate them with a ReferenceQueue held in the map. Whenever the map is accessed, check the ReferenceQueue to see if anything has been added, and if it has, remove its entry from the map. You'll need to make a subclass of WeakReference that holds the key, so you know which entry to remove. You will also need to add a check to methods which query the map (get and containsKey, the iterator methods, etc) to check that a retrieved WeakReference actually contains a value (remember to either ban null values, or use a special sentinel object to represent them).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!