2011-08-11 11 views
10

नौसिखिया सवालसमझौता जावा HashSet के बारे में जावा HashSet की विधि

Set<User> s = new HashSet<User>(); 
User u = new User(); 
u.setName("name1"); 
s.add(u); 
u.setName("name3"); 
System.out.println(s.contains(u)); 

कोई क्यों इस कोड उत्पादन झूठी व्याख्या कर सकते हैं शामिल हैं? इसके अलावा यह कोड उपयोगकर्ता के बराबर विधि को भी कॉल नहीं करता है। लेकिन हैशसेट और हैश मैप के स्रोतों के अनुसार इसे कॉल करना होगा। उपयोगकर्ता के बराबर विधि बस उपयोगकर्ता के नाम पर बराबर कॉल करता है। विधि hashCode उपयोगकर्ता का नाम की वापसी hashCode

+0

आप को लागू किया था बनाने के लिए 'User.equals()' विधि ? –

+0

जॉन स्कीट को उद्धृत करने के लिए "हैशसेट्स में ऑब्जेक्ट्स या तो अपरिवर्तनीय होना चाहिए, या आपको हैशसेट (या हैशपैप) में उपयोग किए जाने के बाद उन्हें बदलने में अनुशासन का उपयोग करने की आवश्यकता है।" - http://stackoverflow.com/questions/4718009/mutable-objects-and-hashcode – Qwerky

उत्तर

13

हैश कोड विधि name क्षेत्र के आधार पर तो है, और आप तो वस्तु, तो दूसरा contains जांच नए हैश मान का उपयोग करेगा जोड़ने के बाद इसे बदल, और नहीं मिलेगा जिस वस्तु को आप ढूंढ रहे थे। ऐसा इसलिए है क्योंकि हैश कोड द्वारा HashSet की पहली खोज, इसलिए यदि वह खोज विफल हो जाती है तो वे equals पर कॉल करने से परेशान नहीं होंगे।

एक ही रास्ता है कि यह काम होता है अगर आप नहीं अधिरोहित equals (और इसलिए डिफ़ॉल्ट संदर्भ समानता इस्तेमाल किया गया था) और था तुम भाग्यशाली हो गया और दो वस्तुओं की हैश कोड बराबर थे। लेकिन यह वास्तव में असंभव परिदृश्य है, और आपको उस पर भरोसा नहीं करना चाहिए।

सामान्य तौर पर, आपको चाहिए कभी नहीं अद्यतन एक वस्तु के बाद आप इसे एक HashSet में शामिल किया है, तो है कि परिवर्तन भी अपने hashCode बदल जाएगा।

+0

तो यह हैशसेट में आपके द्वारा जोड़ा गया एक प्रति है? अन्यथा मुझे लगता है कि नेमसेट में ऑब्जेक्ट में नाम 3 होगा – Ced

9

चूंकि आपके नए User में एक अलग हैशकोड है, हैशसेट जानता है कि यह बराबर नहीं है।

हैशसेट्स अपने आइटम अपने हैशकोड के अनुसार स्टोर करते हैं।
HashSet केवल equals फोन करेगा, तो यह एक ही hashCode साथ एक आइटम पाता है, यह सुनिश्चित करें कि दो आइटम वास्तव में बराबर हैं (जैसा कि एक हैश टकराव के खिलाफ)

+1

वास्तव में यह केवल बराबर कॉल करता है यदि हैशकोड बराबर है। इसका अर्थ यह है कि यदि मैं उपयोगकर्ता को अद्यतन करता हूं, जो इसे हैशकोड बदलता है, तो नेस्टेड सरणी जिसमें उनके हैशकोड से जुड़े एंट्री को अपडेट नहीं किया जाएगा। तो इस सरणी पर पुनरावृत्ति उसी हैशकोड के साथ प्रवेश वापस नहीं करेगा। यदि हैशकोड हमेशा वापस आ जाए तो काम करना चाहिए 0) – user12384512

+3

सही। आम तौर पर, एक हैशसेट में म्यूटेबल ऑब्जेक्ट्स डालना एक बुरा विचार है। यदि आप 'हैशकोड() 'वापसी' 0' बनाते हैं, तो आप हैशसेट के सभी प्रदर्शन लाभ खो देंगे, और आप संभवतः प्राप्त होने वाले सबसे धीमे संग्रह के साथ समाप्त हो जाएंगे। – SLaks

+0

मुझे पता है, यह सिर्फ एक उदाहरण है – user12384512

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