সাম্প্রতিক হ্যাশম্যাপের বিপরীতে কেন কোনও সাম্প্রতিক হ্যাশসেট নেই


537

হ্যাশসেট হ্যাশম্যাপ ভিত্তিক।

আমরা যদি HashSet<E>বাস্তবায়নের দিকে নজর রাখি তবে সবকিছুই পরিচালিত হবে HashMap<E,Object>

<E>এর কী হিসাবে ব্যবহৃত হয় HashMap

এবং আমরা জানি যে HashMapএটি থ্রেড নিরাপদ নয়। যে কারণে আমরা ConcurrentHashMapজাভাতে রয়েছি।

এর উপর ভিত্তি করে, আমি বিভ্রান্ত হয়ে পড়েছি যে কেন আমাদের কাছে কোন সমকালীন হ্যাশসেট নেই যা ভিত্তিক হওয়া উচিত ConcurrentHashMap?

আমি মিস করছি এমন আর কিছু আছে কি? আমাকে Setবহু-থ্রেডযুক্ত পরিবেশে ব্যবহার করা দরকার ।

এছাড়াও, আমি তৈরি করতে চান তাহলে আমার নিজের ConcurrentHashSetআমি শুধু প্রতিস্থাপন করে এটি অর্জন করতে পারেন HashMapথেকে ConcurrentHashMapএবং বাকি রেখে হিসাবে?


2
এপিআইটি দেখার পরে, যদি আমি অনুমান করি তবে আমি বলব যে এটি 2 টি কারণের মধ্যে নেমে এসেছে, (1) প্রতিটি সামান্য বিস্তৃত কার্যকারিতার জন্য জাভা এপিআইতে একটি ক্লাস তৈরি করা এড়ানো (2) এর জন্য সুবিধার্থ ক্লাস সরবরাহ করা আরও ঘন ঘন ব্যবহৃত বস্তু। আমি ব্যক্তিগতভাবে লিংকডহ্যাশম্যাপ এবং লিংকডহ্যাশসেটকে পছন্দ করি যেহেতু তারা গ্যারান্টি দেয় যে সন্নিবেশনের আদেশের মতোই, একটি সেট ব্যবহারের একমাত্র কারণ হ'ল অনুলিপি এড়ানো, প্রায়শই আমি এখনও সন্নিবেশ ক্রম বজায় রাখতে চাই।
আলী

1
@ অলি, আমি ব্যক্তিগতভাবে আপনি লিঙ্কডহ্যাশম্যাপ এবং লিঙ্কডহ্যাশসেটটি পছন্দ করেন আপনি আরও বেশি এগিয়ে যাবেন :)

9
কিছুটা পুরানো প্রশ্ন, তবে গুগলে এটি প্রথম ফলাফল হিসাবে, কনকন্টারস্কিপলিস্টসেটের ইতিমধ্যে কনকেনারহ্যাশম্যাপের প্রয়োগ রয়েছে তা জানার জন্য দরকারী হতে পারে। ডকস.ওরকল
ইগর রডরিগেজ

1
আমি জাভা উত্স থেকে যা দেখেছি ConcurrentSkipListSetতা নির্মিত ConcurrentSkipListMap, যা প্রয়োগ করে ConcurrentNavigableMapএবং ConcurrentMap
তালহা আহমেদ খান

উত্তর:


580

এ জাতীয় কোনও বিল্ট নেই ConcurrentHashSetকারণ আপনি সর্বদা মানচিত্র থেকে একটি সেট সংগ্রহ করতে পারেন । যেহেতু বিভিন্ন ধরণের মানচিত্র রয়েছে তাই আপনি প্রদত্ত মানচিত্র (বা মানচিত্রের শ্রেণি) থেকে সেট তৈরি করতে আপনি একটি পদ্ধতি ব্যবহার করেন।

জাভা 8 এর আগে, আপনি ব্যবহার করে সমবর্তী হ্যাশ ম্যাপের সাহায্যে সেট একটি সমবর্তী হ্যাশ তৈরি করুন Collections.newSetFromMap(map)

জাভা 8 (@Matt দ্বারা নির্দিষ্ট), আপনি একটি সহগামী হ্যাশ সেট পেতে পারেন দৃশ্য মাধ্যমে ConcurrentHashMap.newKeySet()। এটি পুরানো থেকে কিছুটা সহজ newSetFromMapযা আপনাকে খালি মানচিত্রের অবজেক্টে পাস করতে হবে। তবে এটি নির্দিষ্ট ConcurrentHashMap

যাইহোক, জাভা ডিজাইনাররা প্রতিবার একটি নতুন মানচিত্র ইন্টারফেস তৈরি করার সময় একটি নতুন সেট ইন্টারফেস তৈরি করতে পারত, তবে তৃতীয় পক্ষগুলি তাদের নিজস্ব মানচিত্র তৈরি করার সময় এই প্যাটার্নটি প্রয়োগ করা অসম্ভব হবে। স্থির পদ্ধতিগুলি নতুন সেটগুলি অর্জন করা ভাল; আপনি নিজের মানচিত্রের প্রয়োগগুলি তৈরি করার পরেও এই পদ্ধতিটি সর্বদা কার্যকর হয়।


4
আমি কি এই কথাটি ঠিক বলতে পারি যে আপনি যদি সেটটি এইভাবে তৈরি করেন তবে আপনি যে ConcurrentHashMapউপকারগুলি পেয়ে যাবেন তা হারাবেন ConcurrentHashMap?
পেসারিয়ার

19
হারানোর কোনও সুবিধা নেই। newSetFromMapএর বাস্তবায়নটি ডকজার.এইচটিএমএল / অ্যাপি / জাভা / উপিল / সংগ্রহগুলি.জভা এইচটিএমএল 3841 লাইনে শুরু হয়েছে । এটি কেবল একটি মোড়ক ....
রায় তোয়াল

4
@ অ্যান্ড্রু, আমি মনে করি একটি "কনকন্টারসেট" ব্যবহারের পিছনে অনুপ্রেরণা এপিআই নয় বরং বাস্তবায়ন - থ্রেড সুরক্ষা কিন্তু সার্বজনীন লক ছাড়াই - উদাহরণস্বরূপ একাধিক একযোগে পড়ে।
উস্তামান সংগীত

5
কনক্র্যান্টস্কিপলিস্টে প্রচুর পরিমাণে (আকারের) ওভারহেড রয়েছে এবং চেহারাগুলি ধীরে ধীরে।
উপস্থাপিত

3
এই পদ্ধতিটি ব্যবহার করার সময় সাবধানতা অবলম্বন করুন, যেহেতু কিছু পদ্ধতি সঠিকভাবে প্রয়োগ করা হয়নি। কেবল লিঙ্কগুলি অনুসরণ করুন: Collections.newSetFromMapএকটি তৈরি করে SetFromMap। উদাহরণস্বরূপ SetFromMap.removeAllপদ্ধতিটি প্রতিনিধিত্ব করে KeySetView.removeAll, যা উত্তরাধিকার সূত্রে প্রাপ্ত হয় ConcurrentHashMap$CollectionView.removeAll। এই পদ্ধতিটি বাল্ক অপসারণের উপাদানগুলিতে অত্যন্ত অদক্ষ। কল্পনা করুন removeAll(Collections.emptySet())কিছু না করে সমস্ত উপাদানকে অনুসরণ করে Map। একটি হচ্ছে ConcurrentHashSetযে corretly বাস্তবায়িত হয় বেশিরভাগ ক্ষেত্রেই ভালো হতে হবে।
বর্জেজ


79

সঙ্গে পেয়ারা 15 আপনার কাছে কেবল ব্যবহার করতে পারেন:

Set s = Sets.newConcurrentHashSet();

12
এটি সর্বদা একটি দুঃস্বপ্ন। আপনার যদি এমন কোনও সেট বা মানচিত্র থাকে যা কোনও সূত্রে নিরাপদ কিনা তা নির্দেশ করে না তবে আপনি সব ধরণের বিপদ এবং বিপর্যয় বজায় রেখে দেখতে পান। আমি সবসময় এমন একটি প্রকার চাই যা সংগ্রহের জন্য থ্রেড সুরক্ষা (বা না) নির্দেশ করে।
মার্টিন কার্স্টেন

11
পদ্ধতির বিবরণটি আক্ষরিক অর্থে "একটি হ্যাশ ম্যাপের সাহায্যে একটি থ্রেড-সেফ সেট তৈরি করে"
কিচিক

16
যেমনটি আমি বলেছি, এখানে একটি কনক্র্যান্টসেট <ই> অনুপস্থিত। এটি নির্দেশ করার জন্য কনকেন্যরহ্যাশম্যাপটি একটি সমকালীন মানচিত্র ইন্টারফেসের সাথে আসে। এটি হ'ল একই কারণে আমি সর্বদা এই কনকেনারসেট ইন্টারফেসটি যুক্ত করি।
মার্টিন কার্স্টেন

35

ভালো লেগেছে রে Toal উল্লিখিত এটা মতই সহজ:

Set<String> myConcurrentSet = ConcurrentHashMap.newKeySet();

1
এটি জাভা 8 লাগবে বলে মনে হয় বাস্তবায়নের দিকে তাকালে এটি কেবল একটি মোড়কের মতো বলে মনে হয় ConcurrentHashMap
মাইগড

20

দেখে মনে হচ্ছে জাভা তার সমকালীন স্কিপলিস্টসেটের সাথে একসাথে সেট বাস্তবায়ন সরবরাহ করে । একটি স্কিপলিস্ট সেট হ'ল একটি বিশেষ ধরণের সেট বাস্তবায়ন। এটি এখনও সিরিয়ালাইজেবল, ক্লোনিয়েবল, ইটারেবল, কালেকশন, নেভিগিয়েটসেট, সেট, সোর্টার্ড ইন্টারফেস প্রয়োগ করে। আপনার যদি কেবল সেট ইন্টারফেসের প্রয়োজন হয় তবে এটি আপনার পক্ষে কাজ করতে পারে।


12
নোট করুন যে ConcurrentSkipListSetএর উপাদানগুলি হওয়া উচিতComparable
ব্যবহারকারী 45432222

যদি আপনাকে সমবর্তী একটি সেট থেকে প্রসারিত করতে হয় তবে এখানে কেবলমাত্র সমাধানটি কাজ করবে।
ndm13

আপনার যখন বাছাই / নেভিগেশন কার্যকারিতা প্রয়োজন হয় না তখনও কনসেন্টারস্কিপলিস্টম্যাপ হ্যাশ টেবিল ব্যবহার না করে বেস ডেটা স্ট্রাকচার হিসাবে গাছ থাকার অপ্রয়োজনীয় পারফরম্যান্স পেনাল্টি যুক্ত করে।
অজিত গঙ্গা

ব্যবহার করবেন না ConcurrentSkipListSetযদি না আপনি একটি চান SortedSet। অ্যাড বা অপসারণের মতো একটি সাধারণ ক্রিয়াকলাপ এ এর ​​জন্য ও (1) হওয়া উচিত HashSet, তবে এ এর ​​জন্য ও (লগ (এন)) হওয়া উচিত SortedSet
benez

16

দ্বারা উল্লেখ হিসাবে এই একটি সম্পাতবিন্দু-সক্ষম HashSet প্রাপ্ত করার সেরা উপায় মানে হয়Collections.synchronizedSet()

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

এটি আমার পক্ষে কাজ করেছিল এবং আমি সত্যিই কারও দিকে ইশারা করতে দেখিনি।

সম্পাদনা এটি বর্তমানে অনুমোদনযুক্ত সমাধানের চেয়ে কম দক্ষ, যেমন ইউজিন নির্দেশ করে, যেহেতু এটি আপনার সেটটিকে কেবল একটি সিঙ্ক্রোনাইজ ডেকরেটারে আবৃত করে, যখন একটি ConcurrentHashMapপ্রকৃতপক্ষে নিম্ন-স্তরের সম্মতি প্রয়োগ করে এবং এটি আপনার সেটটিকে ঠিক জরিমানা হিসাবে ফিরিয়ে আনতে পারে। তাই পরিষ্কার করে দেওয়ার জন্য মিঃ স্টেপেনেনকভকে ধন্যবাদ জানাই।

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


16
synchronizedSetপদ্ধতি মাত্র সৃষ্টি প্রসাধক অধীনে Collectionমোড়ানো পদ্ধতি থ্রেড-নিরাপদ সিঙ্ক্রোনাইজেশন দ্বারা পুরো সংগ্রহে হতে পারে করা। তবে সম্পূর্ণ সংগ্রহের কোনও লক ছাড়াই অ-ব্লকিং অ্যালগরিদম এবং "নিম্ন-স্তরের" সিঙ্ক্রোনাইজেশন ConcurrentHashMapব্যবহার করে প্রয়োগ করা হয় । পারফরম্যান্স কারণে মাল্টি থ্রেড পরিবেশে ... থেকে মোড়কগুলি আরও খারাপ। Collections.synchronized
ইউজিন স্টেপেনেনকোভ

12

Sets.newSetFromMap(map)একটি পেতে আপনি পেয়ারা ব্যবহার করতে পারেন । জাভা 6 এরও সেই পদ্ধতি রয়েছেjava.util.Collections


এটি java.utll.Cલેક્શન এবং সিএইচএম এর সেট এ পাওয়া যায় সাধারণত যাইহোক খারাপ জিনিস।
বেসটসেস

হ্যাঁ, আমি লক্ষ্য করেছি যে এটি জাভা
in-

এটির মূল হ'ল এটি যদি থ্রেডসেফ হয় এবং আমি সত্যিই সন্দেহ করি।
তালহা আহমেদ খান

@ তালা, এটি থ্রেড নিরাপদ, তবে একা থ্রেড সুরক্ষার অর্থ কিছুই নেই

কখনও কখনও এর অর্থ সমস্ত কিছু। এটি অ্যালগরিদমের অংশ না থাকলে এটি সাধারণত একটি পারফরম্যান্স সমস্যা হয় যা সাধারণত এমনভাবে প্রয়োগ করা হয় যাতে সমবর্তী ম্যাপিংয়ের প্রয়োজনীয়তা হ্রাস করা হয়।
মার্টিন কার্স্টেন

5
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;
   }
}

2
আমি ডামি অবজেক্টের পরিবর্তে বুলিয়ান ব্যবহার করতে চাই like এটি একটু বেশি মার্জিত। এছাড়াও এনইউএলএল ব্যবহার করাও সম্ভব, যেহেতু এটি শূন্যপদে ম্যাপ করা হলেও কী সেটে উপলব্ধ।
মার্টিন কার্স্টেন

2
@ মার্টিন কার্স্টেন ফাই, সমকালীন হ্যাশম্যাপ নালাগুলির অনুমতি দেয় না
লরি

2

কেন ব্যবহার করবেন না: java.util.concurrent থেকে copyOnWriteArraySet?


6
কারণ অনুলিপিআরওয়্যারআরয়েসেট কোনও সংগ্রহের কোনও সংগ্রহের পুরো সংগ্রহটি অনুলিপি করে, যা পারফরম্যান্সের প্রভাবের কারণে সর্বদা চাওয়া হয় না। এটি শুধুমাত্র বিশেষ ক্ষেত্রে কাজ করার জন্য ডিজাইন করা হয়েছে।
হাডিয়াশ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.