2013-08-02 13 views
9
/** 
* Returns the empty map (immutable). This map is serializable. 
* 
* <p>This example illustrates the type-safe way to obtain an empty set: 
* <pre> 
*  Map&lt;String, Date&gt; s = Collections.emptyMap(); 
* </pre> 
* Implementation note: Implementations of this method need not 
* create a separate <tt>Map</tt> object for each call. Using this 
* method is likely to have comparable cost to using the like-named 
* field. (Unlike this method, the field does not provide type safety.) 
* 
* @see #EMPTY_MAP 
* @since 1.5 
*/ 
@SuppressWarnings("unchecked") 
public static final <K,V> Map<K,V> emptyMap() { 
    return (Map<K,V>) EMPTY_MAP; 
} 

Powyższa funkcja zwraca niezmienną pustą mapę.Dlaczego mamy niezmienną pustą mapę?

public static final Map EMPTY_MAP = new EmptyMap<>(); 

klasa EmptyMap jest następujący

/** 
* @serial include 
*/ 
private static class EmptyMap<K,V> 
    extends AbstractMap<K,V> 
    implements Serializable 
{ 
    private static final long serialVersionUID = 6428348081105594320L; 

    public int size()       {return 0;} 
    public boolean isEmpty()     {return true;} 
    public boolean containsKey(Object key)  {return false;} 
    public boolean containsValue(Object value) {return false;} 
    public V get(Object key)     {return null;} 
    public Set<K> keySet()      {return emptySet();} 
    public Collection<V> values()    {return emptySet();} 
    public Set<Map.Entry<K,V>> entrySet()  {return emptySet();} 

    public boolean equals(Object o) { 
     return (o instanceof Map) && ((Map<?,?>)o).isEmpty(); 
    } 

    public int hashCode()      {return 0;} 

    // Preserves singleton property 
    private Object readResolve() { 
     return EMPTY_MAP; 
    } 
} 

Jaki jest pożytek z takiej klasy i metody użytkowego? Próbowałem

Map myMap = Collections.emptyMap(); 
myMap.put("Name","John"); 

i dostaję Exception in thread "main" java.lang.UnsupportedOperationException ponieważ kolekcja jest niezmienna nie obsługuje modyfikacji. Więc jaki jest pożytek z takiej struktury danych?

+3

Nie jestem pewien ... ale domyślam się, że jest to pomocne w czymś takim jak wzór obiektu zerowego. Zamiast zwracania zerowego odwołania z metody można zwrócić pustą mapę. – Asha

+0

prawdopodobny duplikat [Collections.emptyMap() vs nowy HashMap()] (http://stackoverflow.com/questions/14846920/collections-emptymap-vs-new-hashmap) – assylias

Odpowiedz

13

Jakie jest zastosowanie takiej klasy i metody użytkowej?

Jeśli wracasz do Map wynik, to często przydatne, aby była ona niezmienna ... Na przykład, można utworzyć niezmiennej mapę, która otacza własne „prawdziwe” dane zamiast albo utworzyć pełną kopię lub zaufaj dzwoniącemu, aby go nie mutować.

Ponadto, jeśli zwracasz wynik o wartości Map, który jest pusty, wygodnie jest nie tworzyć nowego obiektu za każdym razem - każda pusta mapa jest odpowiednikiem każdej innej pustej mapy, więc dobrze jest użyć pojedynczej instancji .

0

Jest używany (razem z emptyList i emptySet), aby zwrócić pustą kolekcję bez potrzeby tworzenia instancji za każdym razem.

4

Twoim przypadku, myślę, że najlepszym wyjaśnieniem niezmiennej Collections.EMPTY_MAP jest następujący:

  1. Pole jest zadeklarowana jako publiczna (dla ułatwienia dostępu). Jeśli nie sprawiają, że ostateczny, to znaczy można przyjść w każdej chwili i mieć trochę kodu:

    //somewhere in your program (or someone else's) 
    Collections.EMPTY_MAP = new EmptyMap<"String","String">("unwantedKey","unwantedValue"); 
    
    //what do you actually want to do 
    Map myMap = Collections.emptyMap(); 
    //you would expect an empty map, but you will get something else 
    

    to będzie bardzo złe dla Ciebie, jak można prawdopodobnie zobaczyć, że jesteś zachowanie programu będzie źle.

  2. Po przeczytaniu Effective Java 2nd edition pozycja 43 (Zwróć puste tablice lub kolekcje, nie wartości zerowe) zaleca się zwrócić pustą kolekcję, więc przy tworzeniu nie będzie konieczne dołączanie kodu manipulatora o wartości null. Możesz także odwoływać się do tego jako Null-Object-Pattern.

    OK, więc co to ma wspólnego z niezmienną EMPTY_COLLECTION (lub MAP w twoim przypadku)? Wyobraź sobie, że używałbyś wielu metod w swojej klasie, i wywołasz metodę, która tworzy grupy elementów z kolekcji i zwraca kolekcję grup, chyba że (wstawiono tu losowy warunek).

    Jak dotąd tak dobrze. Powiedzmy, że zdecydujesz się użyć EMPTY_MAP z Collections (jeśli tam jest, dlaczego nie?).Zwracasz pustą mapę w kilku miejscach, ale w niektórych z nich chcesz ją zmodyfikować. Zmieniono odwołanie EMPTY_MAP na cały kod, który używa tego odwołania (Powoduje to powrót do numeru 1. Pamiętasz zmianę EMPTY_MAP?).

  3. Powód, dla zmniejszenia pamięci i tym podobne. Gdyby nie było niezmienne i tworzyłbyś nowe instancje za każdym razem, gdy chciałbyś mieć pustą mapę, to byś mógł (możesz powiedzieć, surową) pamięć (nie przecieki, ale) wydajność (nie do końca znam termin, ale Masz pomysł). Być może słyszałeś o singleton, to jest to samo.

Proszę. To są trzy główne powody (o których teraz myślę) dla tego, czego potrzebujesz niezmiennego EMPTY_MAP.

I rozwiązaniem problemu, nie powinieneś używać EMPTY_MAP, powinieneś sam je stworzyć. To nie jest takie trudne, a ty pozbywasz się tych paskudnych (strasznych) niezmiennych rzeczy.

Powodzenia!