डुप्लिकेट मान को किसी HashSet / HashMap में जोड़ने से पिछला मान बदल जाता है


137

कृपया नीचे दिए गए कोड के टुकड़े पर विचार करें:

HashSet hs = new HashSet();
hs.add("hi"); -- (1)
hs.add("hi"); -- (2)

hs.size()1 HashSetदेगा क्योंकि डुप्लिकेट को अनुमति नहीं देता है इसलिए केवल एक तत्व संग्रहीत किया जाएगा।

मैं जानना चाहता हूं कि क्या हम डुप्लिकेट तत्व को जोड़ते हैं, तो क्या यह पिछले तत्व को प्रतिस्थापित करता है या यह केवल इसे नहीं जोड़ता है?

इसके अलावा, HashMapएक ही मामले के लिए उपयोग करने से क्या होगा ?

जवाबों:


247

के मामले में HashMap, यह पुराने मूल्य को नए के साथ बदल देता है।

के मामले में HashSet, आइटम सम्मिलित नहीं किया गया है।


1
निश्चित नहीं है कि मैं क्या याद कर रहा हूं, लेकिन स्रोत कोड अन्यथा इंगित करता है? मुझे लगता है कि वे समर्थन पर एक चेक नहीं करते हैं HashMap, तो देखने के लिए keyपहले से ही कॉल करने से पहले से मौजूद है putसमर्थन पर map?
रहस्य

10
@mystarrocks: कुंजी तत्व का तत्व है Set, और इसे कभी भी put()ऑपरेशन द्वारा प्रतिस्थापित नहीं किया जाता है।
केपील

1
आह अब मैं समझ गया। मैं समझ गया कि कुंजी का तत्व है Set, लेकिन अभी एहसास हुआ कि put()केवल मूल्य को ओवरराइड करेगा, कुंजी को नहीं। इस स्थिति में, यह कुंजी फिर से कुंजी के साथ रखा जाता है, जो कुंजी मौजूद और डालने पर जाँच से बेहतर नहीं हो सकता है। किसी भी तरह, मैं समझता हूं कि यह कैसे काम करता है।
१०'१४ को १२:१२ पर रहस्यवाद

बस जिज्ञासु, क्यों HashMap और HashSet ऐसा होना चुनता है?
हेलिन वांग

@ हेलिनवांग: मुझे नहीं लगता कि यह योजना बनाई गई थी, मुझे लगता है कि यह सिर्फ एक HashSetके रूप में लागू होने का एक प्रभाव है HashMap। हालांकि यह जानना मुश्किल है, जब तक कि आप कक्षाओं के डेवलपर्स में से एक नहीं हैं।
केपील

47

पहली चीज़ जो आपको जानने की ज़रूरत है, वह यह है कि HashSetए की तरह कार्य करता है Set, जिसका अर्थ है कि आप अपनी वस्तु को सीधे जोड़ते हैं HashSetऔर इसमें डुप्लिकेट नहीं हो सकते। आप सीधे अपने मूल्य को इसमें जोड़ते हैं HashSet

हालाँकि, HashMapएक Mapप्रकार है। इसका मतलब है कि हर बार जब आप एक प्रविष्टि जोड़ते हैं, तो आप एक कुंजी-मूल्य जोड़ी बनाते हैं।

में HashMapआप डुप्लिकेट मान हो सकते हैं, लेकिन कुंजी नकल नहीं। में HashMapनई प्रविष्टि पुराने एक की जगह लेगा। सबसे हालिया प्रविष्टि में होगा HashMap

HashMap और HashSet के बीच लिंक को समझना:

याद रखें, HashMapडुप्लिकेट कुंजी नहीं हो सकती। दृश्य के पीछे HashSetएक का उपयोग करता है HashMap

जब आप किसी ऑब्जेक्ट को एक में जोड़ने का प्रयास करते हैं HashSet, तो यह प्रविष्टि वास्तव में एक कुंजी के रूप में संग्रहीत की जाती है HashMap- वही HashMapजो दृश्य के पीछे उपयोग की जाती है HashSet। चूंकि इस अंतर्निहित HashMapको एक कुंजी-मूल्य जोड़ी की आवश्यकता है, हमारे लिए एक डमी मूल्य उत्पन्न होता है।

अब जब आप किसी अन्य डुप्लिकेट ऑब्जेक्ट को उसी में सम्मिलित करने का प्रयास करते हैं HashSet, तो यह फिर से HashMapनीचे झूठ की एक कुंजी के रूप में सम्मिलित करने का प्रयास करेगा । हालाँकि, HashMapडुप्लिकेट का समर्थन नहीं करता है। इसलिए, HashSetअब भी उस प्रकार का केवल एक मूल्य होगा। एक साइड नोट के रूप में, हर डुप्लिकेट कुंजी के लिए, क्योंकि हाशसेट में हमारे प्रवेश के लिए उत्पन्न मूल्य कुछ यादृच्छिक / डमी मूल्य है, कुंजी को बिल्कुल भी प्रतिस्थापित नहीं किया गया है। यह कुंजी को हटाने और एक ही कुंजी (डमी मूल्य समान है) को वापस जोड़ने पर ध्यान नहीं दिया जाएगा।

सारांश:

HashMapनकल की अनुमति देता है values, लेकिन नहीं keysHashSetइसमें डुप्लिकेट नहीं हो सकते।

किसी ऑब्जेक्ट का जोड़ सफलतापूर्वक पूरा हुआ है या नहीं, इसके साथ खेलने के लिए, booleanजब आप कॉल करते हैं, तो आप लौटाए गए मान की जांच कर सकते हैं.add() और देख सकते हैं कि यह वापस आता है trueया नहीं false। लौटा trueतो डाला था।


HashMap allows duplicate valuesHashMap नए के साथ पुराने मूल्य को बदल देता है।
एलेक्स। .१

20

डॉक्स इस पर बहुत स्पष्ट हैं: HashSet.add यह नहीं है की जगह:

निर्दिष्ट तत्व को इस सेट में जोड़ता है यदि यह पहले से मौजूद नहीं है। औपचारिक रूप से, इस सेट में निर्दिष्ट तत्व e को जोड़ता है यदि इस सेट में कोई तत्व e2 नहीं है जैसे कि (e == null? E2 == null: e.equals (e2))। यदि इस सेट में पहले से ही तत्व मौजूद है, तो कॉल सेट को अपरिवर्तित छोड़ देता है और गलत वापस आ जाता है।

लेकिन प्रतिस्थापित करेगा :HashMap.put

यदि मानचित्र में पहले कुंजी के लिए मैपिंग शामिल है, तो पुराने मान को बदल दिया जाता है।


4

यह हैशसेट का मामला है, यह इसे प्रतिस्थापित नहीं करता है।

डॉक्स से:

http://docs.oracle.com/javase/6/docs/api/java/util/HashSet.html#add(E )

"निर्दिष्ट तत्व को इस सेट में जोड़ता है अगर यह पहले से मौजूद नहीं है। अधिक औपचारिक रूप से, इस सेट में निर्दिष्ट तत्व ई जोड़ता है यदि इस सेट में कोई तत्व ई 2 नहीं है जैसे (e == null? E2 == null: e.equals? ई 2)))। यदि इस सेट में पहले से ही तत्व मौजूद है, तो कॉल सेट को अपरिवर्तित छोड़ देता है और गलत हो जाता है। "


1

मुझे सही करें अगर मैं गलत हूं, लेकिन आप जो प्राप्त कर रहे हैं वह स्ट्रिंग्स के साथ है, "हाय" == "हाय" हमेशा सच नहीं होता है (क्योंकि वे आवश्यक रूप से एक ही वस्तु नहीं हैं)।

कारण यह है कि आपको 1 का उत्तर मिल रहा है, क्योंकि जेवीएम उन वस्तुओं का पुन: उपयोग करेगा जहां संभव हो। इस मामले में JVM स्ट्रिंग ऑब्जेक्ट का पुन: उपयोग कर रहा है, और इस प्रकार हशमैप / हैशसेट में आइटम को ओवरराइट कर रहा है।

लेकिन आप इस व्यवहार की गारंटी नहीं देते हैं (क्योंकि यह एक अलग स्ट्रिंग ऑब्जेक्ट हो सकता है जिसका मूल्य "हाय" है)। आपके द्वारा देखा गया व्यवहार सिर्फ JVM के अनुकूलन के कारण है।


0

आपको पहले हाश मानचित्र में पुट विधि की जाँच करने की आवश्यकता है क्योंकि हैशसेट का बैकअप हैशटैब द्वारा समर्थित है

  1. जब आप डुप्लिकेट मान जोड़ते हैं तो स्ट्रिंग "वन" हैशसेट में कहें,
  2. एक प्रविष्टि ("एक", PRESENT) हैशमैप में सम्मिलित हो जाएगी (सभी मानों को सेट में जोड़े जाने पर, मूल्य "PRESENT" होगा जो यदि टाइप ऑब्जेक्ट का है)
  3. हैशमैप मानचित्र में प्रविष्टि जोड़ता है और मान लौटाता है, जो इस मामले में "PRESENT" या अशक्त है यदि प्रविष्टि नहीं है।
  4. हैशसेट की जोड़ विधि तब सही साबित होती है यदि हशमप से लौटाया गया मान अशक्त होता है अन्यथा गलत जिसका अर्थ है कि एक प्रविष्टि पहले से मौजूद है ...

0

इसे अलग तरीके से कहने के लिए: जब आप हाशप में एक कुंजी-मूल्य-युग्म सम्मिलित करते हैं, जहाँ कुंजी पहले से मौजूद होती है (एक अर्थ में हैशवेलु () समान मान को समान रूप से देता है) सत्य है, लेकिन दोनों वस्तुएं अभी भी कई मायनों में भिन्न हो सकती हैं ), कुंजी को प्रतिस्थापित नहीं किया गया है लेकिन मान ओवरराइट किया गया है। कुंजी का उपयोग केवल हैशवेलु () प्राप्त करने और इसके साथ तालिका में मान ज्ञात करने के लिए किया जाता है। चूँकि HashSet एक HashMap की कुंजियों का उपयोग करता है और मनमाने ढंग से मूल्यों को सेट करता है, जो वास्तव में (उपयोगकर्ता के लिए) मायने नहीं रखते हैं, परिणामस्वरूप सेट के तत्वों को भी प्रतिस्थापित नहीं किया जाता है।


0

HashMap मूल रूप से शामिल हैं Entry जो बाद में होता है Key(Object)और Value(Object).Internally HashSetहैं HashMapऔर HashMapआप में से कुछ के रूप में मूल्यों को पहले से ही जगह ले कर pointed..but यह वास्तव में कुंजी ??? नहीं बदलता है ..और कि यहाँ चाल है करता है। HashMapअंतर्निहित में कुंजी के रूप में इसका मूल्य रहता हैHashMap और मान है, बस एक डमी ऑब्जेक्ट है। यदि आप HashMap में एक ही मान को फिर से स्थापित करने का प्रयास करते हैं (अंतर्निहित मानचित्र में कुंजी)। यह केवल डमी मूल्य को बदलता है न कि कुंजी (हैशसेट के लिए मान)।

हैशसेट क्लास के लिए नीचे दिए गए कोड को देखें:

public boolean  [More ...] add(E e) {

   return map.put(e, PRESENT)==null;
}

यहाँ e HashSet के लिए मान है लेकिन अंतर्निहित map.and कुंजी के लिए कुंजी को कभी भी प्रतिस्थापित नहीं किया जाता है। आशा है कि मैं भ्रम को दूर करने में सक्षम हूं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.