Was sind einige der Situationen, in denen ich verwenden kann Collections.emptyMap()
? In der Dokumentation heißt es, dass ich diese Methode verwenden kann, wenn meine Sammlung unveränderlich sein soll.
Warum sollte ich eine unveränderliche leere Sammlung wollen? Was ist der Sinn?
java
collections
Vinoth Kumar CM
quelle
quelle
[NSArray array]
, es gibt ein Objekt zurück, das zwar nicht verwendbar ist, aber existiert. Sie können also wie ein normales Objekt damit spielen und erhalten keinen Fehler.Antworten:
Von Effective Java , Artikel # 43 -
"Return empty arrays or collections, not null"
zeigt eine leere Sammlung zurückkehren und vielleicht sogar demonstriert mit diesenemptyList()
,emptySet()
undemptyMap()
Methoden auf die Klasse Collections eine leere Sammlung zu erhalten , die auch den zusätzlichen Vorteil, dass sie unveränderlich ist. Ab Punkt 15"Minimize Mutability"
.Aus Collections-emptySet-Collections-emptyList-Collections
Hinweis: Der folgende Code ist nur ein Beispiel (ändern Sie ihn entsprechend Ihrem Anwendungsfall):
Diese Methoden bieten einige Vorteile:
Sie sind prägnanter, da Sie den generischen Typ der Sammlung nicht explizit eingeben müssen - er wird im Allgemeinen nur aus dem Kontext des Methodenaufrufs abgeleitet.
Sie sind effizienter, weil sie sich nicht die Mühe machen, neue Objekte zu erstellen. Sie verwenden lediglich ein vorhandenes leeres und unveränderliches Objekt wieder. Dieser Effekt ist im Allgemeinen sehr gering, aber gelegentlich (gut, selten) wichtig.
quelle
Set
undHashSet
in Ihren Beispielen empfehlen , da der springende Punkt deremptySet()
Methode und der Freunde (im Gegensatz zu den KonstantenCollections.EMPTY_SET
usw.) darin besteht, dass sie gut mit Generika spielen. Außerdem ist die Verwendung einer Funktion (Rohtypen), die seit Java 5 veraltet ist, keine gute Lehrhilfe.Collection
stattnull
zu verwenden, umExceptions
nicht auf folgende Operationen geworfen zu werden? Die Verwendung einer unveränderlichen Sammlung würde nur zu einer anderen Ausnahme führen, die ich mir vorstelle. Und das Zuweisennull
ist mit Sicherheit nicht weniger effizient als das Zuweisen einer unveränderlichen Konstante.public boolean setExists() { return !myset.equals(Collections.emptySet()); }
Nach meiner persönlichen Erfahrung ist dies zugegebenermaßen sehr nützlich, wenn eine API eine Sammlung von Parametern erfordert, Sie jedoch nichts bereitzustellen haben. Beispielsweise haben Sie möglicherweise eine API, die ungefähr so aussieht und keine Nullreferenzen zulässt:
Wenn Sie eine Abfrage haben, die keine Parameter akzeptiert, ist es sicherlich etwas verschwenderisch, eine HashMap zu erstellen, bei der ein Array zugewiesen wird, wenn Sie einfach die "leere Karte" übergeben können, die praktisch eine Konstante ist, wie sie implementiert ist in
java.util.Collections
.quelle
Hier gibt es zwei verschiedene Konzepte, die zusammen betrachtet seltsam erscheinen. Es ist sinnvoller, wenn Sie die beiden Konzepte getrennt behandeln.
Erstens sollten Sie nach Möglichkeit lieber eine unveränderliche als eine veränderbare Sammlung verwenden. Die Vorteile der Unbeweglichkeit sind an anderer Stelle gut dokumentiert .
Zweitens sollten Sie lieber eine leere Sammlung verwenden, als null als Sentinel zu verwenden. Dies ist hier gut beschrieben . Dies bedeutet, dass Sie viel saubereren und leichter verständlichen Code haben und weniger Stellen, an denen sich Fehler verstecken können.
Wenn Sie also Code haben, für den eine Karte erforderlich ist, ist es besser, eine leere Karte als eine Null zu übergeben, um das Fehlen einer Karte anzuzeigen. Wenn Sie eine Karte verwenden, ist es meistens besser, eine unveränderliche Karte zu verwenden. Aus diesem Grund gibt es eine praktische Funktion, um eine unveränderliche leere Karte zu erstellen.
quelle
Es gibt einige Fälle, in denen Sie unveränderliche Karten, Listen, Mengen oder andere Arten von Sammlungen bevorzugen.
Der erste und wohl wichtigste Anwendungsfall ist, wenn Sie ein Ergebnis einer Abfrage oder einer Berechnung zurückgeben, die eine Menge (oder Liste oder Karte) von Ergebnissen zurückgeben würde, die Verwendung unveränderlicher Datenstrukturen vorzuziehen.
In diesem Fall ziehe ich es vor, unveränderliche Versionen davon zurückzugeben, da dies die tatsächliche Unveränderlichkeit einer Ergebnismenge einer Berechnung viel deutlicher widerspiegelt - unabhängig davon, was Sie später mit den Daten tun, sollte die Menge der Ergebnisse, die Sie von Ihrer Abfrage erhalten haben, dies nicht tun Veränderung.
Der zweite häufige Anwendungsfall ist, wenn Sie ein Argument als Eingabe für eine Methode oder einen Dienst angeben müssen. Es sei denn, Sie erwarten die Eingabesammlung durch den Dienst oder die Methode geändert wird (was normalerweise eine wirklich schlechte Entwurfsidee ist), kann die Übergabe einer unveränderlichen Sammlung anstelle der veränderlichen in vielen Fällen die vernünftige und sichere Wahl sein.
Ich betrachte es als "Pass by Value" -Konvention.
Allgemeiner gesagt - es ist sinnvoll, unveränderliche Datenstrukturen zu verwenden, wenn Daten Modul- oder Dienstgrenzen überschreiten. Dies macht es viel einfacher, über Unterschiede zwischen (unveränderlichem) Input / Output und veränderlichem internen Zustand nachzudenken.
Als sehr vorteilhafter Nebeneffekt ist dies eine erhöhte Sicherheit und Thread-Sicherheit Ihrer Module / Dienste und sorgt für eine sauberere Trennung von Bedenken.
Ein weiterer guter Grund für die Anwendung von
Collections.empty*()
Methoden ist der spürbare Mangel an Ausführlichkeit. In der Zeit vor Java7 mussten Sie, wenn Sie eine generische Sammlung hatten, generische Typanmerkungen überall verteilen.Vergleichen Sie einfach diese beiden Erklärungen:
gegen:
Letzteres gewinnt auf zwei wichtige Arten zweifellos die Lesbarkeit:
fooBarMap
ein anderer nicht leerer Wert zugewiesen wird, indem ich nur nach suche/fooBarMap =/
.quelle
Zum einen können Sie mit Referenzfreigabe davonkommen. Für ein
new HashMap()
etc sind ein zugewiesenes Objekt und möglicherweise einige zusätzliche Elemente erforderlich, um die Daten zu speichern. Sie benötigen jedoch nur eine Kopie einer unveränderlichen leeren Sammlung (Liste, Satz, Karte oder eine andere solche). Dies macht es zu einer offensichtlichen Wahl, wenn eine von Ihnen aufgerufene Methode eine Map akzeptieren, aber nicht bearbeiten muss.Ich schlage vor, Josh Blochs Effective Java zu testen , in dem einige sehr schöne Attribute unveränderlicher Objekte (einschließlich Thread-Sicherheit) aufgeführt sind.
quelle
Dies kann nützlich sein, wenn Sie eine Funktion haben, die eine zurückgibt,
immutable collection
und in einigen Situationen keine Daten zurückgegeben werden müssen, sodass Sie anstelle einer Rückgabe zurückkehrennull
könnenemptyMap()
Es macht Ihren Code einfacher und verhindert
NullPointerException
quelle
Meistens verwenden wir a
constructor
, um ein neues zu erstellenempty map
. Aber dasCollections
methods
bietet ein paar Vorteile, um eineempty map
Nutzung zu schaffenstatic
method
java.util.Collections.emptyMap()
quelle
Aus dem gleichen Grund würden Sie
Collections.unmodifiableMap()
irgendwann verwenden. Sie möchten eine Map-Instanz zurückgeben, die eine Ausnahme auslöst, wenn der Benutzer versucht, sie zu ändern. Es ist nur ein Sonderfall: die leere Karte.quelle
Aus den gleichen Gründen, warum Sie möglicherweise unveränderliche Objekte möchten. In erster Linie, weil Sie nachts sicher schlafen können, wenn Sie wissen, dass mehrere Threads auf dieselbe Instanz eines Objekts zugreifen können und alle dieselben Werte sehen. Wenn Sie keine Elemente in einer Sammlung haben, ist dies immer noch ein gültiger Wert, den Sie beibehalten möchten.
quelle