2015-08-17 38 views
12

Java 8 wprowadzono nowy sposób uzyskania jednoczesnego Set realizacjęConcurrentHashMap.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(); 

Czy istnieje jakikolwiek powód, aby wolą nową metodę?

Jakieś zalety/wady?

+8

Jest krótszy ... – Reimeus

Odpowiedz

5

ConcurrentHashMap.newKeySet() powinien być nieco bardziej wydajny, ponieważ usuwa jeden poziom pośredni. Collections.newSetFromMap(map) opiera się głównie na przekierowaniu operacji do map.keySet(), ale ConcurrentHashMap.newKeySet() jest bardzo blisko samej map.keySet() (tylko z obsługą dodatków).

Jeśli chodzi o funkcjonalność, nie widzę różnicy.

+1

* "tylko z obsługą modyfikacji" * oznacza możliwość * dodawania *? Ponieważ zestawy kluczy zawsze usuwały wsparcie. – dhke

+1

@dhke, zaktualizowany, dzięki. –

+0

'jak usuwa pojedynczy poziom pośredni' - jesteś pewien? Jak widzę, KeySetView nadal deleguje swoją metodę do wewnętrznej mapy. – turbanoff

12

ConcurrentHashMap.newKeySet() to tylko część funkcji znacznie szerszej niż Collections.newSetFromMap(new ConcurrentHashMap<>()).

Różnica staje się jasne, jeśli spojrzeć na ten przykład:

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

Zamiast mapping do Boolean.TRUE jesteś teraz dodając wartość "hello" podczas dodawania nowej wartości do Set.

Dlatego zwrócone Set s mają typ ConcurrentHashMap.KeySetView. Ten typ ma dodatkowe metody dla asking for the backing map, a także which value will be used when adding new keys.


Więc gdy ConcurrentHashMap.newKeySet() wygląda robi to samo co Collections.newSetFromMap(new ConcurrentHashMap<>()) istnieje różnica znaczeniowa, że ​​ten ostatni powiedział, że nie należy korzystać z mapy, potem, gdy pierwsza jest częścią funkcji, która jest przeznaczona do pracy z mapa.

Zobacz Collections.newSetFromMap:

Podany mapa musi być pusty w czasie metoda ta jest wywołany i nie powinny być dostępne bezpośrednio po ta metoda zwraca.

W rzeczywistości, to nie jest jeszcze określone, że Collections.newSetFromMap użyje Boolean.TRUE dla wartości dodanych, nigdy nie powinien zajmować się że tak ...


może być również przydatna, gdy wan zdać Set do kodu, który jawnie żąda ConcurrentHashMap.KeySetView.


Jeśli używasz wynik przy użyciu typu kompilacji Set tylko, nadal istnieje możliwość, że kod, który odbiera że Set użyje instanceof/rodzaj odlewów, aby dowiedzieć się, że wynik ConcurrentHashMap.newKeySet() jest wspierany przez a ConcurrentHashMap, a wynik Collections.newSetFromMap nie powie Ci. Z drugiej strony pozwala to również kodowi na niezamierzone operacje z mapą podkładu w ten sposób ...

+2

Chociaż to prawda, nie widzę, w jaki sposób funkcja ta może być przydatna w przypadku 'ConcurrentHashMap.newKeySet()' ... –

+1

@Tagir Valeev: Dodałem notatkę, która powinna wyjaśnić. – Holger