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

主宰稳场 提交于 2019-12-12 09:37:42

问题


So the Java WeakHashMap lets one create a map whose entries are removed if its keys become weak. But how can I create a Map whose entries are removed when the values in the map become weak? The reason I want to use a map is as a Global Hash Table which keeps track of objects according to their ID's.

ID --->  Object Address

Key ---> Value

(Where ID is a text string)

I want key-value pairs to be removed when the object addresses become weak, not the Strings that point to them. Anyone any thoughts on this?


回答1:


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

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



回答2:


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.




回答3:


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...




回答4:


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).



来源:https://stackoverflow.com/questions/5666452/java-weak-hash-map-need-to-remove-entry-based-on-weakness-of-value-not-key

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