2015-08-17 4 views
12

Java 8 eingeführt neue Art und Weise eine gleichzeitige Set ImplementierungConcurrentHashMap.newKeySet() vs Collections.newSetFromMap()

// Pre-Java-8 way to create a concurrent set 
Set<String> oldStyle = Collections.newSetFromMap(new ConcurrentHashMap<>()); 
// New method in Java 8 
Set<String> newStyle = ConcurrentHashMap.newKeySet(); 

Gibt es einen Grund zu bevorzugen neue Methode zu erhalten?

Alle Vorteile/Nachteile?

+8

Es ist kürzer ... – Reimeus

Antwort

5

ConcurrentHashMap.newKeySet() sollte etwas effizienter sein, da eine einzelne Ebene der Indirektion entfernt wird. Collections.newSetFromMap(map) basiert meist auf der Umleitung der Operationen auf die map.keySet(), aber ConcurrentHashMap.newKeySet() ist sehr nahe an map.keySet() selbst (nur mit Zusätzen Unterstützung).

Bezüglich der Funktionalität sehe ich keinen Unterschied.

+1

* „mit Änderungen Unterstützung nur“ zu tun erlaubt * bedeutet die Fähigkeit, * in *? Weil Keysets immer Unterstützung entfernt haben. – dhke

+1

@dhke, aktualisiert, danke. –

+0

'wie entfernt eine einzige Ebene der Umleitung '- bist du sicher? Wie ich sehen kann, delegiert KeySetView seine Methode immer noch an die interne Map. – turbanoff

12

ConcurrentHashMap.newKeySet() ist nur ein Teil einer Funktion, die viel breiter ist als Collections.newSetFromMap(new ConcurrentHashMap<>()).

Der Unterschied wird deutlich, wenn man sich diesem Beispiel aussehen:

Set<String> set=new ConcurrentHashMap<String,String>().keySet("hello"); 

Statt Mapping Boolean.TRUE Sie jetzt den Wert "hello" hinzuzufügen, wenn ein neuer Wert der Set hinzufügen.

Deshalb haben die zurückgegebenen Set s den Typ ConcurrentHashMap.KeySetView. Dieser Typ verfügt über zusätzliche Methoden für asking for the backing map sowie which value will be used when adding new keys.


So, während ConcurrentHashMap.newKeySet() sieht aus wie das gleiche zu tun wie Collections.newSetFromMap(new ConcurrentHashMap<>()), gibt es den semantischen Unterschied, dass letztere sagt, Sie nicht die Karte später verwenden sollte, während die früheren Teil eines Merkmals ist, die mit der Interaktion ausgelegt ist Karte.

Siehe Collections.newSetFromMap:

Die angegebene Karte zum Zeitpunkt dieser Methode muss leer sein, aufgerufen wird, und soll nicht direkt nach Rückgabe dieser Methode zugegriffen werden.

In der Tat ist es nicht einmal festgelegt, dass Collections.newSetFromMapBoolean.TRUE für zusätzliche verwenden Werte-Sie sollten nie mit dem ohnehin beschäftigen ...


Es könnte auch nützlich sein, wenn Sie die Set passieren wan Code, der explizit eine anfordert.


Wenn Sie das Ergebnis verwenden Set die Kompilierung-Typ mit nur gibt es immer noch die Möglichkeit, dass Code, der empfängt, dass Setinstanceof/Typ verwenden wirft, um herauszufinden, dass das Ergebnis der ConcurrentHashMap.newKeySet() durch gesichert ist a ConcurrentHashMap während das Ergebnis von Collections.newSetFromMap wird Ihnen nicht sagen. Auf der anderen Seite, die auch Code unbeabsichtigte Dinge mit BackingMap auf diese Weise ...

+2

Während das stimmt, sehe ich nicht, wie diese Funktion nützlich sein kann mit 'ConcurrentHashMap.newKeySet()' ... –

+1

@Tagir Valeev: Ich habe eine Notiz hinzugefügt, die es deutlich machen sollte. – Holger

Verwandte Themen