Kodėl nėra ConcurrentHashSet vs ConcurrentHashMap

„HashSet“ yra pagrįstas „HashMap“.

Jei pažvelgsime į „ HashSet<E> , viskas bus tvarkoma„ HashMap<E,Object> .

<E> naudojamas kaip „ HashMap raktas.

Ir mes žinome, kad „ HashMap nėra saugus. Štai kodėl „Java“ yra „ ConcurrentHashMap “.

Atsižvelgdamas į tai, aš supainiuosi, kodėl mes neturime „ConcurrentHashSet“, kuris turėtų būti pagrįstas „ ConcurrentHashMap ?

Ar yra kažkas, ką aš praleidau? Turiu naudoti „ Set “ daugiapakopėje aplinkoje.

Be to, jei noriu sukurti savo „ ConcurrentHashSet , ar galiu ją pasiekti tiesiog pakeičiant „ HashMap su „ ConcurrentHashMap ir paliekant viską, kas yra?

329
09 авг. pateikė Talha Ahmed Khan 09 rug. 2011-08-09 10:14 '11 at 10:14 2011-08-09 10:14
@ 9 atsakymai

ConcurrentHashSet nėra integruoto tipo, nes visada galite gauti rinkinį iš žemėlapio. Kadangi yra daug žemėlapių tipų, naudokite metodą tam tikro žemėlapio (arba žemėlapio klasės) rinkinio sukūrimui.

Prieš „Java 8“, sukuriate lygiagrečią maišos rinkinį, palaikomą lygiagrečiu maišos žemėlapiu, naudodami Collections.newSetFromMap(map)

„Java 8“ (pažymėtas @Matt), galite gauti vienu metu reprezentuojamą maišos rinkinį per „ ConcurrentHashMap.newKeySet() . Tai yra šiek tiek paprastesnis nei senas newSetFromMap , kuris reikalavo, kad būtų perduotas tuščias žemėlapio objektas. Bet tai būdinga „ ConcurrentHashMap .

Bet kokiu atveju „Java“ kūrėjai gali sukurti naują individualią sąsają kiekvieną kartą, kai buvo sukurta nauja žemėlapio sąsaja, tačiau nebūtų įmanoma užtikrinti šio šablono, kai trečiosios šalys sukuria savo žemėlapius. Geriau turėti statinius metodus, kurie gamina naujus rinkinius; Šis požiūris visada veikia, net jei kuriate savo žemėlapio įgyvendinimą.

361
09 авг. atsakymą pateikė Ray Toal 09 rug . 2011-08-09 10:17 '11, 10:17, 2011-08-09 10:17
 Set<String> mySet = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>()); 
68
23 июня '14 в 12:21 2014-06-23 12:21 atsakymą pateikė Serge Maskva birželio 23 d., 14 val. 12:21 2014-06-23 12:21

Su „ Guava 15“ taip pat galite naudoti:

 Set s = Sets.newConcurrentHashSet(); 
47
01 февр. atsakymas pateikiamas kichik 01 feb . 2015-02-01 23:35 '15, 23:35, 2015-02-01 23:35

Atrodo, kad Java suteikia lygiagretų rinkinį su ConcurrentSkipListSet . „ SkipList“ rinkinys yra specialios rūšies įgyvendinimas. Jis vis dar įgyvendina sąsajas Serializable, Cloneable, Iterable, Collection, NavigableSet, Set, SortedSet. Tai gali būti naudinga, jei jums reikia tik „Set“ sąsajos.

14
02 окт. atsakymą pateikė Mike Pone 02 okt. 2013-10-02 19:17 '13, 7:17 pm 2013-10-02 19:17

Jūs galite naudoti guava Sets.newSetFromMap(map) kad gautumėte. Java 6 taip pat turi šį būdą java.util.Collections

12
09 авг. atsakymas, kurį Bozho pateikė rugpjūčio 9 d. 2011-08-09 10:17 '11, 10:17 2011-08-09 10:17

Kaip tai nurodyta, geriausias būdas pasiekti suderinamumą „HashSet“ yra su Collections.synchronizedSet()

 Set s = Collections.synchronizedSet(new HashSet(...)); 

Jis dirbo man, ir nematau, kad kas nors iš tiesų tai nurodytų.

EDIT Tai mažiau veiksminga nei šiuo metu suderintas sprendimas, kaip pažymi Eugene, nes jis tiesiog perkelia jūsų rinkinį į sinchronizuotą dekoratorių, o „ ConcurrentHashMap iš tikrųjų įgyvendina žemo lygio sutapimą ir taip pat gali padėti jūsų rinkinį. Taigi ačiū p. Stepanenkovui už tai aiškiai.

http://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#synchronizedSet-java.util.Set-

10
05 нояб. Atsakymą pateikė Nirro lapkričio 5 d. 2014-11-05 21:56 '14, 21:56 2014-11-05 21:56

Kaip minėjo Ray Toal , tai taip paprasta, kaip:

 Set<String> myConcurrentSet = ConcurrentHashMap.newKeySet(); 
7
07 июля '16 в 20:28 2016-07-07 20:28 atsakymas pateikiamas „ BullyWiiPlaza“ liepos 07 d. 16:28 2016-07-07 20:28
 import java.util.AbstractSet; import java.util.Iterator; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; public class ConcurrentHashSet<E> extends AbstractSet<E> implements Set<E>{ private final ConcurrentMap<E, Object> theMap; private static final Object dummy = new Object(); public ConcurrentHashSet(){ theMap = new ConcurrentHashMap<E, Object>(); } @Override public int size() { return theMap.size(); } @Override public Iterator<E> iterator(){ return theMap.keySet().iterator(); } @Override public boolean isEmpty(){ return theMap.isEmpty(); } @Override public boolean add(final E o){ return theMap.put(o, ConcurrentHashSet.dummy) == null; } @Override public boolean contains(final Object o){ return theMap.containsKey(o); } @Override public void clear(){ theMap.clear(); } @Override public boolean remove(final Object o){ return theMap.remove(o) == ConcurrentHashSet.dummy; } public boolean addIfAbsent(final E o){ Object obj = theMap.putIfAbsent(o, ConcurrentHashSet.dummy); return obj == null; } } 
4
Atsakymas yra MD. 25 сент. Mohiuddin Ahmed Rugsėjo 25 d 2014-09-25 08:53 '14, 8:53, 2014-09-25 08:53

Kodėl gi ne naudoti: CopyOnWriteArraySet iš java.util.concurrent?

2
07 окт. atsakymas, kurį pateikė Shendor 07 spalis 2016-10-07 17:56 '16 at 17:56 pm 2016-10-07 17:56