2012-05-15 17 views
15

creo un WeakHashMap comoejemplo WeakHashMap

WeakHashMap<Employee,String> map = new WeakHashMap<Employee,String>(); 
map.put(emp,"hello"); 

donde emp es un objeto Employee. Ahora si hago emp = null o dice que el objeto emp ya no se referencia, ¿se eliminará la entrada de WeakHashMap, es decir, el tamaño de Map será cero?
¿Y será viceversa en el caso de HashMap?
¿Es correcto mi entendimiento de WeakHashMap?

Respuesta

6

me encontré con el código de ejemplo para entender la diferencia entre HashMap y WeakHashMap

  Map hashMap= new HashMap(); 
      Map weakHashMap = new WeakHashMap(); 

      String keyHashMap = new String("keyHashMap"); 
      String keyWeakHashMap = new String("keyWeakHashMap"); 

      hashMap.put(keyHashMap, "helloHash"); 
      weakHashMap.put(keyWeakHashMap, "helloWeakHash"); 
      System.out.println("Before: hash map value:"+hashMap.get("keyHashMap")+" and weak hash map value:"+weakHashMap.get("keyWeakHashMap")); 

      keyHashMap = null; 
      keyWeakHashMap = null; 

      System.gc(); 

      System.out.println("After: hash map value:"+hashMap.get("keyHashMap")+" and weak hash map value:"+weakHashMap.get("keyWeakHashMap")); 

La salida será:

Before: hash map value:helloHash and weak hash map value:helloWeakHash 
After: hash map value:helloHash and weak hash map value:null 
6

* ¿Se eliminará la entrada del WeakHashMap, es decir, el tamaño de Map será cero? *

Si emp contenía la última referencia haciendo que el Empleado strongly reachable entonces la entrada en el mapa puede ser eliminado.

docs El Java resume bastante bien:

Una aplicación de mapas basados ​​en tabla hash con claves débiles. Una entrada en un WeakHashMap se eliminará automáticamente cuando su clave ya no esté en uso ordinario. Más precisamente, la presencia de un mapeo para una clave dada no impedirá que la clave sea descartada por el recolector de basura [...]. Cuando se descarta una clave, su entrada se elimina efectivamente del mapa, por lo que esta clase se comporta de forma algo diferente a otras implementaciones de Mapas.

 

¿Y será viceversa en caso de HashMap?

La eliminación de la entrada del WeakHashMap no afectará a ninguna otra referencia en el programa.

+0

Sí, un WeakHashMap contiene referencias débiles a los objetos. Una referencia débil tiene su puntero "desactivado" si el recolector de basura descubre que (y otras referencias débiles) es la última referencia restante al objeto. Pero esto solo ocurre en ciertos ciclos de GC. A primera vista, no sé qué ocurre con el conteo del mapa cuando esto ocurre. –

+0

@aioobe "Si el comando emp incluyó la última referencia que hace al Empleado plenamente accesible, la entrada en el mapa puede eliminarse". No lo entendí ¿Puedes por favor elaborar más? – Anand

+0

@anand, si 'emp' era la única variable que hacía referencia a' Empleado' (aparte de otras referencias * débiles * como la del mapa hash), entonces hacer 'emp = null' hará que el empleado en cuestión elegible para la recolección de basura. Lea sobre [accesibilidad] (http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ref/package-summary.html#reachability). – aioobe

35

Un ejemplo muy sencillo, para iluminar a lo que ya se ha dicho:

import java.util.WeakHashMap; 

public class WeakHashMapDemo { 

    public static void main(String[] args) { 
     // -- Fill a weak hash map with one entry 
     WeakHashMap<Data, String> map = new WeakHashMap<Data, String>(); 
     Data someDataObject = new Data("foo"); 
     map.put(someDataObject, someDataObject.value); 
     System.out.println("map contains someDataObject ? " + map.containsKey(someDataObject)); 

     // -- now make someDataObject elligible for garbage collection... 
     someDataObject = null; 

     for (int i = 0; i < 10000; i++) { 
      if (map.size() != 0) { 
       System.out.println("At iteration " + i + " the map still holds the reference on someDataObject"); 
      } else { 
       System.out.println("somDataObject has finally been garbage collected at iteration " + i + ", hence the map is now empty"); 
       break; 
      } 
     } 
    } 

    static class Data { 
     String value; 
     Data(String value) { 
      this.value = value; 
     } 
    } 
} 

Salida:

map contains someDataObject ? true 
    ... 
    At iteration 6216 the map still holds the reference on someDataObject 
    At iteration 6217 the map still holds the reference on someDataObject 
    At iteration 6218 the map still holds the reference on someDataObject 
    somDataObject has finally been garbage collected at iteration 6219, hence the map is now empty 
+0

¡Para mí tomó mucho más tiempo! Tuve que cambiar el programa :) "somDataObject finalmente ha sido basura recogida en la iteración 708693, por lo tanto, el mapa está ahora vacío" –

+0

@Yanflea Me costó trabajo preguntarme qué pasaría con la referencia débil en el mapa cuando la referencia real es GCed . Su ejemplo dejó muy claro que la referencia débil sería eliminada del mapa. Gracias una tonelada. – tMJ

1

Las referencias en java son la dirección de memoria donde los objetos creados apuntan en la memoria. En un WeakHashMap, se utiliza el concepto de referencia débil.

Tan pronto como cree un objeto en Java y lo asigne a alguna variable, se volverá muy accesible.

El objeto de referencia débil puede ser algo similar al objeto que no tiene referencias de memoria, es decir, puede ser basura ahora.

1

En otras implementaciones de Map como HashMap, las claves son muy accesibles.Por ejemplo, si un HashMap tiene claves como clase Person como se muestra a continuación y si el objeto Person se establece en nulo, incluso después de esto si hacemos map.get (Person) obtendremos el valor de la memoria ya que las claves están fuertemente referenciadas en un HashMap.

wm.put(person, person.getFirstName()); 
person = null; 
System.gc(); 
System.out.println("Hash Map :" + wm.toString()); 

Salida: Mapa Hash: {} [email protected]=John

En comparación con HashMap, WeakHashMap es la que va a eliminar sus enteries tan pronto como las teclas tienen ninguna referencia en la memoria. Por ejemplo, si un WeakHashMap tiene claves como clase Person como se muestra a continuación y si el objeto Person se establece en nulo, ahora si haces map.get (Person) obtendremos null de él porque la clave no tiene referencia (o más bien débilmente) accesible).

wm.put(person, person.getFirstName()); 
person = null; 
System.gc(); 
System.out.println("Weak Hash Map :" + wm.toString()); 

Salida: Débil Hash Mapa: {}

0

ejemplo WeakHashMap:

Map map = new WeakHashMap(); 
Foo foo = new Foo(); 
map.put(foo, "bar"); 
foo=null; // strong refrence is removed and object is available for garbage collection. 

ejemplo HashMap:

Map map = new HashMap(); 
Foo foo = new Foo(); 
map.put(foo, "bar"); 
foo=null; // even though the reference is nullified object will not garbage collected because map is having Strong refrence.