2015-08-17 24 views
12

Java 8 ha introdotto nuovo modo per ottenere un concomitante Set implementazioneConcurrentHashMap.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(); 

C'è qualche motivo per preferire nuovo metodo?

Eventuali vantaggi/svantaggi?

+8

È più breve ... – Reimeus

risposta

5

ConcurrentHashMap.newKeySet() dovrebbe essere un po 'più efficiente in quanto rimuove un singolo livello di riferimento indiretto. Collections.newSetFromMap(map) si basa principalmente sul reindirizzamento delle operazioni allo map.keySet(), ma ConcurrentHashMap.newKeySet() è molto vicino allo stesso map.keySet() (solo con il supporto per le aggiunte).

Per quanto riguarda la funzionalità, non vedo differenze.

+1

* "solo con supporto modifiche" * che significa la possibilità di * aggiungere *? Perché i keyset hanno sempre rimosso il supporto. – dhke

+1

@dhke, aggiornato, grazie. –

+0

'as rimuove un singolo livello di riferimento indiretto '- sei sicuro? Come posso vedere KeySetView ancora delega il suo metodo alla mappa interna. – turbanoff

12

ConcurrentHashMap.newKeySet() è solo una parte di una funzionalità che è molto più ampia di Collections.newSetFromMap(new ConcurrentHashMap<>()).

La differenza diventa evidente se si guarda a questo esempio:

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

Invece di mappatura per Boolean.TRUE ora si sta aggiungendo il valore "hello" quando si aggiunge un nuovo valore al Set.

Ecco perché il Set restituito ha il tipo ConcurrentHashMap.KeySetView. Questo tipo ha metodi aggiuntivi per asking for the backing map e which value will be used when adding new keys.


Così, mentre ConcurrentHashMap.newKeySet() sembra fare lo stesso come Collections.newSetFromMap(new ConcurrentHashMap<>()), v'è la differenza semantica che quest'ultimo dice che non si dovrebbe usare la mappa successivamente, mentre il primo è parte di una caratteristica che è stato progettato per interagire con il carta geografica.

Vedi Collections.newSetFromMap:

La mappa specificato deve essere vuoto al momento questo metodo viene richiamato, e non è possibile accedere direttamente dopo questo metodo restituisce.

In realtà, non è nemmeno specificato che Collections.newSetFromMap utilizzerà Boolean.TRUE per Plusvalore-non si dovrebbe mai fare con questo in ogni caso ...


Potrebbe anche essere utile quando si wan per passare il Set al codice che richiede esplicitamente un ConcurrentHashMap.KeySetView.


Se si utilizza il risultato utilizzando il tipo in fase di compilazione Set solo, c'è ancora la possibilità che il codice che riceve che Set utilizzerà instanceof/tipo di calchi di scoprire che il risultato di ConcurrentHashMap.newKeySet() è sostenuta da a ConcurrentHashMap mentre il risultato di Collections.newSetFromMap non lo dirà. D'altra parte, ciò consente anche al codice di fare cose non intenzionali con la mappa di supporto in questo modo ...

+2

Anche se è vero, non vedo come questa funzione possa essere utile con 'ConcurrentHashMap.newKeySet()' ... –

+1

@Tagir Valeev: Ho aggiunto una nota che dovrebbe chiarire. – Holger