2012-05-15 13 views
15

utworzyć WeakHashMap jakoWeakHashMap przykład

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

gdzie EMP Przedmiotem pracownika. Teraz, jeśli robię emp = null lub mówię, że obiekt emp nie jest już przywoływany, to czy wpis zostanie usunięty z WeakHashMap, tzn. Czy rozmiar mapy będzie wynosił zero?
I czy będzie odwrotnie w przypadku HashMap?
Czy moje rozumienie WeakHashMap jest poprawne?

Odpowiedz

6

wpadłem przykładowego kodu, aby zrozumieć różnicę między HashMap i 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")); 

Dane wyjściowe będą następujące:

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

* będzie wpis zostać usunięte z WeakHashMap czyli będzie wielkość mapą wynosić zero? *

Jeśli emp zawierał ostatni odniesienie podejmowania Pracownika strongly reachable następnie wpis w mapie może zostać usunięte.

docs Java podsumowuje to całkiem dobrze:

hashtable oparte realizacja Mapa ze słabych kluczy. Wpis w WeakHashMap zostanie automatycznie usunięty, gdy jego klucz nie będzie już w zwykłym użyciu. Dokładniej, obecność mapowania dla danego klucza nie zapobiegnie odrzuceniu klucza przez śmieciarz [...]. Po odrzuceniu klucza jego wpis jest skutecznie usuwany z mapy, więc ta klasa zachowuje się nieco inaczej niż inne implementacje Map.

 

I to będzie na odwrót w przypadku HashMap?

Usuwanie wpisu z WeakHashMap nie wpłynie na żadne inne odniesienia w programie.

+0

Tak, A WeakHashMap zawiera słabe odniesienia do obiektów. Słaby odnośnik ma wskaźnik "zapped", jeśli garbage collector odkryje, że to (i inne słabe referencje) jest ostatnim pozostałym odniesieniem do obiektu. Ale dzieje się tak tylko w niektórych cyklach GC. Z drugiej strony, nie wiem, co dzieje się z licznikiem mapy, kiedy to nastąpi. –

+0

@aioobe "Jeśli emp zawierał ostatni numer referencyjny, dzięki czemu Pracownik jest mocno osiągalny, wówczas wpis na mapie może zostać usunięty." Nie dostałem tego. Czy mógłbyś rozwinąć więcej? – Anand

+0

@anand, Jeśli 'emp' była jedyną zmienną, która odniosła się do jakiegoś' Employee' (oprócz innych * słabych * odniesień, takich jak ten na mapie mieszania), to zrobienie 'emp = null' spowoduje, że dany pracownik kwalifikuje się do zbierania śmieci. Czytaj na temat [dostępność] (http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ref/package-summary.html#reachability). – aioobe

35

bardzo prosty przykład, aby oświecić, co zostało już powiedziane:

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

wyjściowa:

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

Dla mnie zajęło to znacznie dłużej! Musiał zmienić program :) "somDataObject w końcu został wyrzucony ze śmieci w iteracji 708693, stąd mapa jest teraz pusta" –

+0

@Yanflea Miałem ciężki czas zastanawiając się, co stałoby się ze słabym odniesieniem na mapie, gdy rzeczywiste odniesienie jest GCed . Twój przykład bardzo wyraźnie pokazał, że słaby ref zostałby usunięty z mapy. Dzięki za tonę. – tMJ

1

Odniesienia w java to adres pamięci, w którym utworzone obiekty znajdują się w pamięci. W WeakHashMap używana jest koncepcja słabego odniesienia.

Zaraz po utworzeniu obiektu w java i przypisaniu go do pewnej zmiennej, staje się on zdecydowanie osiągalny.

Słaby obiekt odniesienia może być nieco podobny do obiektu, który nie ma odniesień do pamięci, tzn. Może być teraz usunięty z pamięci.

1

W innych implementacjach Map, takich jak HashMap, klucze są bardzo dostępne.Na przykład, jeśli HashMap ma klucze jako klasa Person, jak pokazano poniżej i jeśli obiekt Person ma wartość null, nawet po tym, jeśli zrobimy map.get (Person), otrzymamy wartość z pamięci, ponieważ klucze są silnie odwołane w HashMap.

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

wyjściowe: Hash mapa {[email protected]=John}

porównaniu do HashMap, WeakHashMap jest ten, który usunie swoje enteries najszybciej jak klawisze nie mają odniesienia w pamięci. Na przykład, jeśli WeakHashMap ma klucze jako klasę Person jak pokazano poniżej i jeśli obiekt Person ma wartość null, teraz jeśli zrobisz map.get (Person), otrzymamy null z niego, ponieważ klucz nie ma odniesienia (lub raczej słabo osiągalny).

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

wyjściowa: słaby Hash mapa {}

0

WeakHashMap przykład:

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. 

przykład 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.