webentwicklung-frage-antwort-db.com.de

Ersetzt das Hinzufügen eines doppelten Werts zu einer HashSet/HashMap den vorherigen Wert

Bitte beachten Sie den folgenden Code:

HashSet hs = new HashSet();
hs.add("hi"); -- (1)
hs.add("hi"); -- (2)

hs.size() gibt 1 aus, da HashSet keine Duplikate zulässt, sodass nur ein Element gespeichert wird.

Ich möchte wissen, ob wir das doppelte Element hinzufügen. Ersetzt es dann das vorherige Element oder fügt es einfach nicht hinzu? 

Was passiert auch mitHashMap für den gleichen Fall?

114
Anand

Bei HashMap wird der alte Wert durch den neuen ersetzt. 

Im Falle von HashSet wird der Artikel nicht eingefügt.

205
Keppil

Das erste, was Sie wissen müssen, ist, dass HashSet wie ein Set fungiert. Dies bedeutet, dass Sie Ihr Objekt direkt zum HashSet hinzufügen und keine Duplikate enthalten können. Sie fügen einfach Ihren Wert direkt in HashSet hinzu. 

HashMap ist jedoch ein Map-Typ. Das heißt, jedes Mal, wenn Sie einen Eintrag hinzufügen, fügen Sie ein Schlüssel-Wert-Paar hinzu.

In HashMap können Sie doppelte Werte haben, nicht aber Schlüssel. In HashMap ersetzt der neue Eintrag den alten. Der neueste Eintrag befindet sich in der HashMap.

Link zwischen HashMap und HashSet verstehen:

Denken Sie daran, dass HashMap keine doppelten Schlüssel haben kann. Hinter den Kulissen verwendet HashSet ein HashMap.

Wenn Sie versuchen, ein Objekt in ein HashSet-Objekt einzufügen, wird dieser Eintrag tatsächlich als Schlüssel in HashMap gespeichert - das gleiche HashMap, das hinter der Szene von HashSet verwendet wird. Da dieses zugrundeliegende HashMap ein Schlüsselwertpaar benötigt, wird für uns ein Dummy-Wert generiert.

Wenn Sie nun versuchen, ein weiteres doppeltes Objekt in dasselbe HashSet-Objekt einzufügen, wird es erneut versuchen, es als Schlüssel in das darunter liegende HashMap-Objekt einzufügen. HashMap unterstützt jedoch keine Duplikate. Daher führt HashSet immer nur einen Wert dieses Typs. Als Randbemerkung wird für jeden doppelten Schlüssel ein zufälliger/Dummy-Wert verwendet, da der für unseren Eintrag in HashSet generierte Wert ein beliebiger Wert ist. Es wird ignoriert, da der Schlüssel entfernt wird und derselbe Schlüssel wieder hinzugefügt wird (der Dummy-Wert ist derselbe). Dies macht überhaupt keinen Sinn.

Zusammenfassung:

HashMap erlaubt das Duplizieren von values, jedoch nicht keys. HashSet darf keine Duplikate enthalten. 

Um zu spielen, ob das Hinzufügen eines Objekts erfolgreich abgeschlossen wurde oder nicht, können Sie den beim Aufruf von .add() zurückgegebenen boolean-Wert überprüfen und prüfen, ob er true oder false zurückgibt. Wenn true zurückgegeben wurde, wurde es eingefügt.

41
Jimmy

Die docs sind hier ziemlich klar: HashSet.addersetzt nicht:

Fügt dem Satz das angegebene Element hinzu, wenn es noch nicht vorhanden ist. Fügt formal das angegebene Element e zu dieser Gruppe hinzu, wenn diese Gruppe kein Element e2 enthält, also (e == null? E2 == null: e.equals (e2)). Wenn dieser Satz das Element bereits enthält, lässt der Aufruf den Satz unverändert und gibt false zurück. 

Aber HashMap.putwird ersetzen:

Wenn die Zuordnung zuvor eine Zuordnung für den Schlüssel enthielt, wird der alte Wert ersetzt. 

17
pb2q

Bei HashSet ersetzt es NICHT.

Aus den Dokumenten:

http://docs.Oracle.com/javase/6/docs/api/Java/util/HashSet.html#add(E )

"Fügt dem Satz das angegebene Element hinzu, wenn es nicht bereits vorhanden ist. Fügt das angegebene Element e formal zu diesem Satz hinzu, wenn dieser Satz kein Element e2 enthält, so dass (e == null? E2 == null: e.equals ( e2)). Wenn dieser Satz das Element bereits enthält, lässt der Aufruf den Satz unverändert und gibt false zurück. "

4
Bob Provencher

Korrigieren Sie mich, wenn ich falsch liege, aber was Sie bekommen, ist, dass "Hi" == "Hi" nicht immer wahr ist (weil sie nicht unbedingt dasselbe Objekt sind).

Der Grund, warum Sie eine Antwort von 1 erhalten, ist, dass die JVM String-Objekte nach Möglichkeit wiederverwendet. In diesem Fall verwendet die JVM das String-Objekt erneut und überschreibt damit das Element im Hashmap/Hashset. 

Dieses Verhalten ist jedoch nicht garantiert (da es sich um ein anderes String-Objekt handeln kann, das den gleichen Wert "Hi" hat). Das Verhalten, das Sie sehen, ist nur auf die Optimierung der JVM zurückzuführen.

1
Nick Rippe

Um es anders zu sagen: Wenn Sie ein Schlüssel-Wert-Paar in eine HashMap einfügen, wo der Schlüssel bereits vorhanden ist (in gewisser Weise ergibt Hashwert () den gleichen Wert und Equal () ist wahr, die beiden Objekte können sich jedoch in mehrfacher Hinsicht unterscheiden ), der Schlüssel wird nicht ersetzt, der Wert wird jedoch überschrieben. Der Schlüssel wird nur verwendet, um den Hashwert () abzurufen und den Wert in der Tabelle damit zu finden .. Da HashSet die Schlüssel einer HashMap verwendet und beliebige Werte festlegt, die für den Benutzer nicht wirklich wichtig sind Die Elemente des Sets werden ebenfalls nicht ersetzt.

0
Marco Rothley

HashMap enthält im Wesentlichen Entry, die anschließend Key(Object) und Value(Object) enthält. Intern HashSet sind HashMap und HashMap Werte ersetzen, da einige von Ihnen bereits darauf hingewiesen haben. Aber ersetzt sie wirklich die Tasten ??? HashMap behält ihren Wert als Schlüssel im zugrunde liegenden HashMap und value ist nur ein Dummy-Objekt. Wenn Sie also versuchen, denselben Wert erneut in HashMap (Schlüssel in der zugrundeliegenden Map) einzufügen, wird der Dummy-Wert und nicht der Schlüssel (Wert für HashSet) .

Sehen Sie sich den folgenden Code für HashSet-Klasse an:

public boolean  [More ...] add(E e) {

   return map.put(e, PRESENT)==null;
}

Hier ist e der Wert für HashSet, aber der Schlüssel für die zugrunde liegende Karte. Der Schlüssel wird niemals ersetzt. Ich hoffe, ich bin in der Lage, die Verwirrung zu beseitigen.

0
Kunal Kumar

Sie müssen zuerst die Put-Methode in der Hash-Map überprüfen, da HashSet von HashMap gesichert wird

  1. Wenn Sie einen doppelten Wert hinzufügen, sagen Sie einen String "Eins" in HashSet,
  2. Ein Eintrag ("one", PRESENT) wird in Hashmap eingefügt (für alle in___ eingegebenen Werte wird der Wert "PRESENT" sein, wenn vom Typ Object)
  3. Hashmap fügt den Eintrag in Map hinzu und gibt den Wert zurück, der in diesem Fall "PRESENT" oder null ist, wenn Entry nicht vorhanden ist.
  4. Die add-Methode von Hashset gibt dann true zurück, wenn der von Hashmap zurückgegebene Wert gleich Null ist, andernfalls false, was bedeutet, dass bereits ein Eintrag vorhanden ist ...
0
shiv