Frage

Die JavaDoc von ConcurrentHashMap dies sagt:

  

Wie Hashtable aber im Gegensatz zu HashMap diese Klasse tut nicht erlaubt null als Schlüssel oder Wert verwendet werden.

Meine Frage: Warum?

2. Frage: warum Hashtable nicht null zulassen

Ich habe eine Menge von HashMaps zum Speichern von Daten verwendet. Aber bei einem Wechsel ConcurrentHashMap ich wegen Nullpointerexceptions mehrmals in Schwierigkeiten geraten.

War es hilfreich?

Lösung

Vom Autor von ConcurrentHashMap selbst (Doug Lea) :

  

Der Hauptgrund, die NULL-Werte in ConcurrentMaps sind nicht erlaubt   (ConcurrentHashMaps, ConcurrentSkipListMaps) ist, daß Mehrdeutigkeiten, die   kann sein kann gerade noch erträglich in nicht-gleichzeitige Karten nicht   gebracht. Die wichtigste davon ist, dass, wenn map.get(key) kehrt null, Sie   kann nicht erkennen, ob explizit der Schlüssel zum null abbildet vs der Schlüssel nicht ist   abgebildet. In einer nicht-gleichzeitigen Karte können Sie dies überprüfen, über   map.contains(key), aber in einer gleichzeitig ein, die Karte könnte sich geändert haben   zwischen den Anrufen.

Andere Tipps

Ich glaube, es ist, zumindest teilweise, damit Sie containsKey und get in einen einzigen Aufruf kombinieren. Wenn die Karte nulls halten kann, gibt es keine Möglichkeit zu sagen, ob get einen Null zurückkehrt, weil es kein Schlüssel für diesen Wert war, oder einfach nur, weil der Wert war null.

Warum ist das ein Problem? Denn es gibt keinen sicheren Weg, dass selbst zu tun. Nehmen Sie den folgenden Code ein:

if (m.containsKey(k)) {
   return m.get(k);
} else {
   throw new KeyNotPresentException();
}

Da m eine gleichzeitige Karte ist, kann Schlüssel k zwischen den containsKey und get Anrufen gelöscht werden, so dass dieser Schnipsel ein Null zurückzugeben, die nie in der Tabelle war, anstatt die gewünschten KeyNotPresentException.

Normalerweise würde man das lösen durch Synchronisieren, aber mit einer gleichzeitigen Karte, dass natürlich wird nicht funktionieren. Daher hatte die Signatur für get zu ändern, und der einzige Weg, das zu tun, in einem rückwärtskompatiblen Art und Weise dem Benutzer das Einfügen von Nullwerten in erster Linie zu verhindern war, und weiterhin mit, dass als ein Platzhalter für „Schlüssel nicht gefunden“.

Josh Bloch entworfen HashMap; Doug Lea entworfen ConcurrentHashMap. Ich hoffe, dass nicht verleumderisch ist. Eigentlich denke ich, das Problem ist, dass NULL-Werte oft Verpackung erfordern, so dass die reale Null für nicht initialisierte stehen kann. Wenn Client-Code nulls erfordert dann kann es die (zugegebenermaßen klein) Kosten für die Verpackung nulls selbst zahlen.

ConcurrentHashMap ist Thread-sicher. Ich glaube, dass nicht erlaubt null Schlüssel und Werte waren ein Teil dafür zu sorgen, dass es Thread-sicher ist.

Ich denke, dass der folgende Ausschnitt aus der API-Dokumentation einen guten Hinweis gibt: „Diese Klasse ist vollständig kompatibel mit Hashtable in Programmen, die auf seiner Thread-Sicherheit verlassen, aber nicht auf seinen Synchronisation Details.“

Sie wollten wahrscheinlich nur ConcurrentHashMap voll kompatibel / austauschbar Hashtable machen. Und als Hashtable erlaubt keine Null-Schlüssel und Werte ..

Sie können nicht auf einem Null synchronisieren.

Edit: Das ist nicht genau, warum in diesem Fall. Ich dachte zunächst, es war etwas Phantasie geht mit Dingen gegen gleichzeitige Aktualisierungen Sperren oder auf andere Weise den Objekt Monitor zu erkennen, ob etwas geändert, aber bei der Prüfung der Quellcode es scheint, ich falsch war - sie eine Sperre mit "Segment" basiert auf einer Bitmaske der Hash.

In diesem Fall ich vermute, sie haben es geschafft Hashtable zu kopieren, und ich vermute, Hashtable tat es, weil in der relationalen Datenbank Welt, null! = Null, so mit einem Null als Schlüssel keine Bedeutung hat.

Ich glaube nicht Nullwert nicht anzuerkennen ist eine richtige Option. In vielen Fällen wollen wir mit Nullwert in die con-aktuellen Karte eine Schlüssel do setzen. Jedoch durch ConcurrentHashMap verwenden, können wir das nicht tun. Ich schlage vor, dass die kommende Version von JDK kann man erkennen, unterstützen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top