2013-08-02 10 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; 
} 

Die obige Funktion gibt eine unveränderbare leere Map zurück.Warum haben wir eine unveränderliche leere Karte?

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

EmptyMap Klasse ist als

/** 
* @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; 
    } 
} 

folgt Was ist die Verwendung solcher Klasse und Dienstprogramm-Methode? Ich habe versucht,

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

und ich Exception in thread "main" java.lang.UnsupportedOperationException weil Sammlung unveränderlich ist keine Modifikation unterstützen. Also, was ist die Verwendung einer solchen Datenstruktur?

+3

Ich bin mir nicht sicher..aber meine Vermutung ist, dass dies in etwas wie ein Null-Objekt-Muster hilfreich ist. Anstatt eine Nullreferenz von einer Methode zurückzugeben, können Sie eine leere Map zurückgeben. – Asha

+0

mögliches Duplikat von [Collections.emptyMap() vs. new HashMap()] (http://stackoverflow.com/questions/14846920/collections-emptymap-vs-new-hashmap) – assylias

Antwort

13

Was ist die Verwendung solcher Klasse und Dienstprogramm-Methode?

Wenn Sie ein Map Ergebnis sind Rückkehr, ist es oft nützlich, um es unveränderlich ... zum Beispiel sein, können Sie eine unveränderliche Karte erstellen, die eher Ihre eigenen „echten“ Daten wickelt als zu, die entweder erstellen vollständige Kopie, oder vertrauen Sie dem Aufrufer, es nicht zu mutieren.

Wenn Sie ein Map Ergebnis zurückgeben, das leer ist, ist es praktisch, dass Sie nicht jedes Mal ein neues Objekt erstellen müssen - jede leere Karte ist äquivalent zu jeder anderen leeren Karte. Daher ist es sinnvoll, eine einzelne Instanz zu verwenden .

0

Es verwendet wird (zusammen with emptyList und emptySet), um eine leere Collection zurückzugeben, ohne jedes Mal ein neues Objekt instanziieren zu müssen.

4

Für Ihren Fall, ich denke, die beste Erklärung für unveränderlich Collections.EMPTY_MAP ist die folgende:

  1. Das Feld als public deklariert wird (für einen leichten Zugang). Wenn Sie nicht es endgültig machen, dann können Sie jederzeit kommen kann und ein wenig Code wie dieses:

    //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 
    

    dies sehr schlecht für Sie, wie Sie wahrscheinlich sehen, dass Sie das Verhalten des Programms sind wird falsch sein.

  2. Wenn Sie Effective Java 2nd edition Element 43 lesen (leere Arrays oder Sammlungen zurückgeben, keine Nullen), wird empfohlen, eine leere Collection zurückzugeben, sodass Sie bei der Entwicklung keinen Null-Array-Manipulationscode einfügen müssen. Sie können dies auch als Null-Object-Pattern bezeichnen.

    OK, also was hat das mit unveränderlicher EMPTY_COLLECTION (oder MAP in Ihrem Fall) zu tun? Stellen Sie sich vor, Sie würden viele Methoden in Ihrer Klasse verwenden, und Sie rufen eine Methode auf, die Gruppen von Elementen aus einer Sammlung erstellt und eine Sammlung der Gruppen zurückgibt, sofern (zufällige Bedingung hier eingefügt).

    So weit so gut. Nehmen wir an, Sie entscheiden sich für die EMPTY_MAP von Collections (wenn es da ist, warum nicht?).Sie geben die leere Map an mehreren Stellen zurück, in einigen möchten Sie sie jedoch ändern. Sie ändern den Verweis EMPTY_MAP auf all Ihren Code, der diese Referenz verwendet (Dies bringt uns zurück zu Nummer 1. Merken Sie sich die Änderung in EMPTY_MAP?).

  3. Dieser Grund, wenn für Speicherreduktion und solche Sachen. Wenn es nicht unveränderlich wäre und du jedes Mal neue Instanzen erstellen würdest, wenn du eine leere Karte haben willst, würde das (man könnte sagen ernsthaft) Gedächtnis (nicht Lecks, aber) Leistung (ich weiß den Begriff nicht genau, aber Du hast die Idee). Vielleicht haben Sie von singleton gehört, das ist das Gleiche.

Dort gehen Sie. Dies sind die 3 wichtigsten Gründe (die ich mir im Moment vorstellen kann) für das, was Sie als unveränderliche EMPTY_MAP benötigen.

Und eine Lösung für Ihr Problem, sollten Sie EMPTY_MAP nicht verwenden, sollten Sie selbst erstellen. Es ist nicht so schwer und du wirst diese fiesen (unheimlichen) unveränderlichen Dinge los.

Viel Glück!

Verwandte Themen