Re: WeakHashMap for values
- From: Rogan Dawes <discard@xxxxxxxxxxxx>
- Date: Thu, 08 Jun 2006 18:30:11 +0200
Hendrik Maryns wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi,
I need something like WeakHashMap, but with the inverse function: I want
the values to be weakly referenced to, and the entry to be discarded
from the map once the value no longer exists. Is there a standard
implementation for this?
But maybe, as happens often, I am saying: I want X, whereas actually I
want Y, but think I need X to achieve it. So here is my real problem:
I have some small wrapper objects, whose identity is determined by the
array of some other objects they contain. I want to avoid unnecessary
implementations of those wrappers, so I wanted to write a factory
method. The first idea is to have a Map mapping lists to objects
(arrays do not give good hash codes, so I convert them with
Arrays.asList first). Now, the whole idea is to save memory, so I don’t
want this map to get unnecessarily big. The idea is: using weak
references I can have it clean up itself. But WeakHashMap does just the
inverse: it weakly wraps the key, not the value. And using the
suggestion in the javadoc will not work too, I think: I can wrap the
values myself, but the keys are lists made on the fly, so the weak hash
map will throw those entries away too soon!
One solution I see, is to use an ordinary HashMap, wrap the values in
weak references, and do some cleanup in the map from time to time. But
I am not sure how I should implement ‘from time to time’, then.
Suggestions welcome!
Depending on the size of your HashMap, you could do it whenever someone gets or puts a value.
e.g. if they do
map.get(foo), and the value referenced by foo has gone away, simply return null, and remove the entry for foo from the map.
e.g. (typed in my mail client, and not carefully checked)
public class WeakValueHashMap extends HashMap {
// necessary constructors . . .
public Object put(Object key, Object value) {
WeakReference old = null;
if (value != null) {
old = (WeakReference) super.put(key, new WeakReference(value));
} else {
old = (WeakReference) super.put(key, null);
}
if (old != null) {
return old.get();
}
return null;
}
public Object get(Object key) {
WeakReference value = (WeakReference) super.get(key);
if (value == null) return null;
return value.get();
}
private void prune() {
Iterator it = keySet().iterator();
while (it.hasNext()) {
Object key = it.next();
WeakReference value = super.get(key);
if (value != null && value.get() == null) {
it.remove();
}
}
}
}
Depending on how you plan to use the class, you should probably wrap calls to entrySet, keySet() and values(), etc with a call to prune first, as well as making sure that each of the values returned have been suitably dereferenced.
Hope this helped.
Rogan
.
- Follow-Ups:
- Re: WeakHashMap for values
- From: Hendrik Maryns
- Re: WeakHashMap for values
- References:
- WeakHashMap for values
- From: Hendrik Maryns
- WeakHashMap for values
- Prev by Date: Re: JSP Help Needed
- Next by Date: Re: WeakHashMap for values
- Previous by thread: WeakHashMap for values
- Next by thread: Re: WeakHashMap for values
- Index(es):
Relevant Pages
|