2012-05-15 10 views
15

Creo WeakHashMap comeesempio WeakHashMap

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

dove emp è un oggetto dipendente. Ora se faccio emp = null o dico emp oggetto non è più referenziato, allora la voce verrà rimossa da WeakHashMap, la dimensione di Map sarà zero?
E sarà viceversa in caso di HashMap?
La mia comprensione di WeakHashMap è corretta?

risposta

6

Ho eseguito il codice di esempio per capire la differenza tra HashMap e 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")); 

L'output sarà:

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

* la voce verrà rimossa dalla WeakHashMap vale a dire la dimensione della mappa sarà zero? *

Se emp conteneva l'ultimo riferimento rendendo l'Employee strongly reachable poi la voce nella mappa può essere rimosso.

documenti Java riassume abbastanza bene:

Un'implementazione Mappa tabella hash-based con chiavi deboli. Una voce in una WeakHashMap verrà automaticamente rimossa quando la sua chiave non è più in uso normale. Più precisamente, la presenza di una mappatura per una data chiave non impedisce che la chiave venga scartata dal garbage collector [...]. Quando una chiave è stata scartata, la sua entrata viene effettivamente rimossa dalla mappa, quindi questa classe si comporta in modo leggermente diverso dalle altre implementazioni della mappa.

 

E sarà viceversa in caso di HashMap?

La rimozione della voce da WeakHashMap non influisce su altri riferimenti nel programma.

+0

Yep, un WeakHashMap contiene riferimenti deboli agli oggetti. Un riferimento debole ha il suo puntatore "zapped" se il garbage collector scopre che esso (e altri riferimenti deboli) è l'ultimo riferimento rimasto all'oggetto. Ma questo succede solo su alcuni cicli di GC. A mano a mano, non so cosa succede al conteggio della mappa quando questo accade. –

+0

@aioobe "Se emp conteneva l'ultimo riferimento rendendo il Dipendente fortemente raggiungibile allora la voce nella mappa può essere rimossa." Non l'ho capito Puoi per favore elaborare di più? – Anand

+0

@anand, se 'emp' era l'unica variabile che si riferiva ad alcuni' Employee' (a parte altri * deboli * riferimenti come quello nella mappa hash), quindi fare 'emp = null' renderà il dipendente in questione ammissibile per la raccolta dei rifiuti. Leggi su [raggiungibilità] (http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ref/package-summary.html#reachability). – aioobe

35

Un esempio molto semplice, per illuminare ciò che è già stato detto:

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; 
     } 
    } 
} 

uscita:

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

Per me ci è voluto molto più tempo! Dovuto cambiare il programma :) "somDataObject è stato finalmente garbage collection con iterazione 708693, quindi la mappa è vuota" –

+0

@Yanflea Ho avuto difficoltà a chiedermi cosa sarebbe successo al riferimento debole nella mappa quando il riferimento reale è GCed . Il tuo esempio ha reso estremamente chiaro che il ref debole sarebbe stato rimosso dalla mappa. Grazie mille. – tMJ

1

Il riferimento in java è l'indirizzo di memoria in cui gli oggetti creati puntano nella memoria. In una WeakHashMap viene utilizzato il concetto di riferimento debole.

Non appena si crea un oggetto in java e lo si assegna ad alcune variabili, diventa fortemente raggiungibile.

L'oggetto di riferimento debole può essere in qualche modo simile all'oggetto che non ha riferimenti di memoria, ovvero può essere raccolto automaticamente.

1

In altre implementazioni Mappa come una HashMap, le chiavi sono fortemente raggiungibili.Ad esempio, se una HashMap ha le chiavi come classe Person come mostrato di seguito e se l'oggetto Person è impostato su null, anche dopo questo se faremo map.get (Person) otterremo il valore dalla memoria poiché le chiavi sono fortemente referenziate in una HashMap.

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

uscita: Hash Mappa: {} [email protected]=John

Rispetto al HashMap, WeakHashMap è quella che rimuoverà i suoi enteries non appena i tasti hanno alcun riferimento nella memoria. Ad esempio, se una WeakHashMap ha le chiavi come classe Person come mostrato di seguito e se l'oggetto Person è impostato su null, ora se si esegue map.get (Person) otterremo null da esso perché la chiave non ha riferimenti (o piuttosto debolmente raggiungibile).

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

uscita: Debole Hash Mappa: {}

0

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

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