2015-05-04 11 views
11

HashSet wird mit HashMap implementiert und wenn wir etwas zu HashSet e1 hinzufügen, fügt es intern (e1, neues Object()) in die HashMap ein, wenn e1 nicht in der Menge vorhanden war. Meine Frage ist, warum sie neue Object() einfügen, wenn sie wie (e1, null) eingefügt hätten, was eine optimierte Methode ist, da keine neuen Objekte erstellt werden. Gibt es Nachteile beim Einfügen von Nullen?Warum erstellt die interne Implementierung von HashSet Dummy-Objekte, die als Werte in HashMap eingefügt werden, anstatt Nullen einzufügen?

+0

Es werden keine neuen Objekte hinzugefügt. Es fügt eine einzige hinzu, die als Indikator für das Vorhandensein eines Wertes in der Menge verwendet wird. Lesen Sie den Quellcode. –

+0

In Java 8 haben sie es geändert in private statische endgültige Objekt PRESENT = new Object(); , das ist der Wert. – Sandeep

+0

Es gibt keine Leistungseinbußen, weil das Objekt statisch ist, so dass es nur eine Konstante ist, und es wird als Dummy-Wert funktionieren – Prashant

Antwort

11

Eine HashSet fügt kein neues Object jedes Mal, wenn ein neuer Schlüssel put in der Karte ist. Es verwendet eine Object, aber es verwendet die gleiche Object jedes Mal. Dieser Wert wird PRESENT in dem Quellcode HashSet benannt.

Die Methode add ruft put(key, PRESENT) auf dem internen HashMap auf. Die remove-Methode ruft remove(key) auf dem internen HashMap auf, aber es muss einen boolean zurückgeben, der angibt, ob der Schlüssel vorhanden war. Wenn null als Wert gespeichert wurde, muss HashSet zunächst containsKey und dann remove aufrufen, um festzustellen, ob der Schlüssel vorhanden war - zusätzlicher Overhead. Hier ist nur der Speicheraufwand von Object minimal.

0

z. Wenn Sie dem ConcurrentSkipListSet-Konstruktor ein HashSet-Objekt zuweisen, darf er keine Nullwerte enthalten.

2

Ich sah sie nur an den Sourcecode und sah diesen Code

public boolean add(E e) { 
    return map.put(e, PRESENT)==null; 
} 

public boolean remove(Object o) { 
    return map.remove(o)==PRESENT; 
} 

Diese würden nicht funktionieren, wenn null statt PRESENT verwendet wurde; in jedem Fall wäre ein zusätzlicher Schritt erforderlich.