2015-09-13 10 views
13

शामिल मैं अक्सर अपने आप निम्न कार्य लगता है:HashSet बनाम ArrayList प्रदर्शन

HashSet<String> set = new HashSet<String>(); 
//Adding elements to the set 
ArrayList<String> list = new ArrayList<String> (set); 

कुछ की तरह "डंपिंग" सूची में सेट की सामग्री। मैं आमतौर पर ऐसा करता हूं क्योंकि मेरे द्वारा जोड़े गए तत्वों में अक्सर डुप्लिकेट होते हैं जिन्हें मैं निकालना चाहता हूं, और यह उन्हें हटाने का एक आसान तरीका प्रतीत होता है।

मन में ही नहीं उद्देश्य से

(परहेज डुप्लिकेट) मैं भी लिख सकते हैं:

ArrayList<String> list = new ArrayList<String>(); 
// Processing here 
if (! list.contains(element)) list.add(element); 
//More processing here 

और इस तरह की सूची में सेट "डंपिंग" के लिए कोई जरूरत नहीं। हालांकि, मैं प्रत्येक तत्व डालने से पहले एक छोटे से जांच कर रही होगी

दो संभावनाएं के किसी भी स्पष्ट रूप से और अधिक कुशल है (जो मैं HashSet संभालने कर रहा हूँ के रूप में अच्छी तरह से करता है)?

+0

आपके पास प्रश्न का पहला हिस्सा गलत है। डुप्लिकेट से छुटकारा पाने के लिए आप सेट में डंपिंग सूची कर रहे हैं, दूसरी तरफ नहीं, है ना? – MirMasej

+0

आप इसका परीक्षण क्यों नहीं करते? बीटीडब्ल्यू सेट को किसी सूची में परिवर्तित करने के साथ परेशान क्यों है? सेट के माध्यम से जाना शायद बड़े सरणी के लिए तेजी से होगा। – luk32

+0

हाय, आपकी टिप्पणियों के लिए धन्यवाद। इस परिदृश्य में मैं डेटा के साथ अपने सेट को पॉप्युलेट करता हूं (डुप्लिकेट से बचने के लिए) और उसके बाद इसे एक सूची में डंप करता हूं, इस तरह से मैं प्रभावी रूप से कोई डुप्लीज़ वाली सूची प्राप्त करता हूं। अगर मुझे सूची की आवश्यकता नहीं है तो मैं वास्तव में एक नहीं बनाऊंगा, लेकिन कभी-कभी एक प्रकार का एक प्रकार लागू होता है, और मेरे द्वारा काम किए जाने वाले कुछ कोड सूचियों की आवश्यकता होती है। – Jorge

उत्तर

30

सेट बेहतर प्रदर्शन (O(n) बनाम सूची के लिए O(n^2)) दे देंगे, और क्योंकि डुप्लिकेट से बचने बहुत उद्देश्य एक सेट के है कि सामान्य है।

शामिल के लिए एक HashSet है O(1) एक सूची के लिए O(n) की तुलना में है, इसलिए यदि आप एक सूची का उपयोग कभी नहीं होना चाहिए अगर आप अक्सर contains चलाने की जरूरत है।

+0

क्या होगा यदि सूची में केवल कुछ तत्व हैं? –

+1

जटिलता गणना वास्तव में बाध्य समस्याओं पर लागू नहीं होती है। इसका लक्ष्य यह समझना है कि समस्या का आकार कितना धीमा हो जाता है जब समस्या का आकार बढ़ता है, जो असीम रूप से बड़ा हो जाता है। उसने कहा, मुझे नहीं लगता कि 'शामिल' ऑपरेशन के लिए हैश सेट पर एक सूची का उपयोग करने का कोई फायदा नहीं है। निश्चित रूप से, एक सेट में सामान्य रूप से एक बड़ी मेमोरी ओवरहेड होती है, लेकिन यदि आपके पास कुछ तत्व हैं तो आप भी क्यों परवाह करेंगे? बाध्य डेटासेट (उदाहरण के लिए 'एनमसेट') के लिए अधिक कुशल सेट कार्यान्वयन मौजूद हैं, लेकिन आमतौर पर एक साधारण हैश सेट सामान्य प्रदर्शन आवश्यकताओं के लिए पर्याप्त होना चाहिए – Dici

+0

अक्सर हमारे पास पहले से ही एक अल्पकालिक सूची होती है जिसके लिए हमें '.contains' चलाने की आवश्यकता होती है। सवाल यह है कि सेट बनाने के लिए किस आकार से यह समझ में आता है? 10 तत्वों के तहत दोनों 1-2 माइक्रोस्कोप के पैमाने पर प्रदर्शन करते हैं, लेकिन हम सेट बनाने के लिए समय बिताते हैं। वैसे भी, यहां कोई बेंचमार्क है यदि कोई दिलचस्पी है https://gist.github.com/ibalashov/0138e850e58942569a636dffa75f0bb9 –

6

ArrayList डेटा भंडारण के लिये एक सरणी का उपयोग करता है। ArrayList.contains ओ (एन) जटिलता का होगा। इसलिए अनिवार्य रूप से सरणी में बार-बार खोजना O(n^2) जटिलता होगी।

जबकि HashSet उनके संबंधित बाल्टी में तत्वों के भंडारण के लिए हैशिंग तंत्र का उपयोग करता है। HashSet का संचालन मूल्यों की लंबी सूची के लिए तेज़ होगा। यह O(1) में तत्व तक पहुंच जाएगा।

3

आप एक सूची की जरूरत नहीं है, मैं सिर्फ एक सेट का प्रयोग करेंगे और इस प्राकृतिक संग्रह करता है, तो आदेश कोई फर्क नहीं पड़ता और आप डुप्लिकेट अनदेखा करना चाहते का प्रयोग है।

आप दोनों क्या कर सकते हैं आप डुप्लिकेट के बिना एक सूची की जरूरत है।

private Set<String> set = new HashSet<>(); 
private List<String> list = new ArrayList<>(); 


public void add(String str) { 
    if (set.add(str)) 
     list.add(str); 
} 

इस तरह इस सूची में केवल अनन्य मानों में शामिल होंगे, मूल प्रविष्टि आदेश में संरक्षित है और ऑपरेशन हे है (1)।

+3

यदि ऑर्डर मायने रखता है, तो 'लिंक्ड हैशसेट' की तुलना में मैं उल्लेख करता हूं, या एक ट्रीसेट 'अगर कोई सॉर्टिंग ऑर्डर होता है आवश्यकता – Dici

+0

इतना आसान और बहुत सुरुचिपूर्ण! मुझे पसंद है! – Jorge

+0

@ जॉर्ज नोट: Set.add (x) केवल तभी सच होता है जब इसे पहली बार जोड़ा गया था। –

0

आप सूची ही तत्व जोड़ सकते हैं। फिर, dedup के लिए -

HashSet<String> hs = new HashSet<>(); // new hashset 
hs.addAll(list); // add all list elements to hashset (this is the dedup, since addAll works as a union, thus removing all duplicates) 
list.clear(); // clear the list 
list.addAll(hs); // add all hashset elements to the list 

तुम सिर्फ dedup के साथ एक सेट की जरूरत है, तो आप भी addAll() एक अलग सेट पर, उपयोग कर सकते हैं इतना है कि यह केवल अनन्य मान होगा।

संबंधित मुद्दे