2011-11-08 4 views
8

Necesito asociar algunos datos con una clave durante su vida útil, entonces estoy usando un WeakHashMap. Sin embargo, además necesito obtener una clave por su valor correspondiente. La manera más fácil de hacerlo es aferrarse a la referencia al crear un valor:¿Se recolectará una entrada de WeakHashMap si el valor contiene la única referencia fuerte a la clave?

public class Key {} 

public class Value { 
    final public Key key; 
    public Value(Key k) { 
     key = k; 
    } 
} 

Por supuesto, mientras que yo uso en mi Value programa, su key no va a desaparecer. Sin embargo, si no hay más referencias a cualquiera de las claves o su valor fuera del mapa, ¿se recolectará basura? ¿O la referencia fuerte que sobrevive en el valor lo previene?

Respuesta

13

No, no se recoge la basura, ver el Javadoc: Nota

Implementación: Los objetos de valor en una WeakHashMap se llevan a cabo por las referencias fuertes corrientes. Por lo tanto, se debe tener cuidado para asegurar que los objetos de valor no se refieran fuertemente a sus propias claves, ya sea directa o indirectamente, ya que eso evitará que las claves sean descartadas.

Según lo mencionado por @biziclop, una solución sería almacenar una referencia débil a la clave en su objeto de valor.

public class Value { 
    final public WeakReference<Key> key; 
    public Value(Key k) { 
    this.key = new WeakReference<Key>(k); 
    } 
} 
+1

+1 Tal vez debería haber leído la documentación primero. :) – biziclop

+0

@biziclop También desde el Javadoc: Una forma de lidiar con esto es envolver los valores en WeakReferences antes de insertarlos, como en: m.put (clave, nueva WeakReference (value)), y luego desenvolver en cada get. ¡Eso debería hacer el truco! – laguille

+0

O eso o solo almacena una referencia débil a la clave en tus objetos de valor. Porque si ajusta el valor en un WR, podría terminar con una clave existente con el valor alraedy recopilado. – biziclop

2

En cuanto a la implementación, la respuesta parece ser no.

Esta es la fuente de WeakHashMap:

/** 
* The table, resized as necessary. Length MUST Always be a power of two. 
*/ 
private Entry[] table; 

... 

private static class Entry<K,V> extends WeakReference<K> implements Map.Entry<K,V> { 
    private V value; 
    ... 
} 

Como se puede ver, se hace referencia a objetos Entry fuertemente por el propio mapa. Entonces, si el mapa es accesible, también lo será el Entry, por lo tanto, sus objetos Value y su clave también.

Cuestiones relacionadas