2012-12-19 13 views
6

मैं बस यह सुनिश्चित करना चाहता हूं कि सुरक्षितInteger ऑब्जेक्ट्स को चाबियों के रूप में उपयोग कर रहा है। यहाँ एक छोटी उदाहरण है:इंटीजर कुंजी के साथ जावा मानचित्र: चाबियाँ कैसे तुलना की जाती हैं?

Integer int1 = new Integer(1337); 
Integer int2 = new Integer(1337); 

if (int1 == int2) { 
    System.out.println("true"); 
} else { 
    System.out.println("false"); 
} 

if (int1.equals(int2)) { 
    System.out.println("true"); 
} else { 
    System.out.println("false"); 
} 

Map<Integer, Object> map = new HashMap<Integer, Object>(); 
map.put(int1, null); 
map.put(int2, null); 

System.out.println(map.size()); 

कोड इच्छा उत्पादन

false 
true 
1 

है यही तो मैं उम्मीद कर रहा था, संदर्भ अलग लेकिन वे एक दूसरे के बराबर है। अब मुझे मानचित्र के व्यवहार में रूचि है।

  • क्या यह गारंटी है कि मानचित्र या सेट जैसे संग्रह उनकी सामग्री से कुंजी की तुलना करेंगे, न कि उनके संदर्भ से?
  • या वास्तविक कार्यान्वयन पर निर्भर करता है, जैसे HashMap?
+0

@close: यह एक डुप्लिकेट नहीं है - प्रश्न में अन्य पोस्ट "बराबर बनाम ==" के मामले को संभालती है, जबकि यह सवाल संग्रह में एक पहचानकर्ता के रूप में कितना अच्छा व्यवहार करेगा!यही कारण है कि नीचे बुलेट बिंदु हैं। मैं पूछ रहा हूं: संग्रह कैसे संभालते हैं। – Scolytus

उत्तर

7

विधि equals कहा जाता है, इसलिए यह तुलना की जाने वाली सामग्री है।

ऊपर अपने दो प्रश्नों के रूप में:

दो वस्तुओं o1 और o2 (आसान बनाने के लिए, हम मानते हैं कि o1!=null और o2!=null), एक कुंडी नक्शा, अंततः, यह निर्धारित करने के अगर वे एक ही मूल्य है है को देखते हुए। (अंततः, HaspMap से भी जांचता है कि o1 और o2 के पास हैश मान है, लेकिन यह आपके प्रश्न के संदर्भ में महत्वपूर्ण नहीं है)। यह विधि equals() पर कॉल करके करता है। जब तक o1.equals(o2) गलत है, तो दो वस्तुओं को HashMap द्वारा दो अलग-अलग कुंजी माना जाता है।

HashSet यह भी निर्धारित करने के लिए equals() पर कॉल करता है कि यह निर्धारित करने के लिए कि कोई तत्व पहले से सेट में है या नहीं, http://docs.oracle.com/javase/6/docs/api/java/util/HashSet.html#add%28E%29 देखें।

TreeMap, दूसरी ओर, दो वस्तुओं की तुलना करना है, और यह निर्धारित करना है कि वे बराबर हैं या कौन सा बड़ा है। यह compareTo() पर कॉल करके करता है। इसलिए, यह o1.compareTo(o2) का वापसी मान है जो महत्वपूर्ण है (या, यदि आपने निर्माता http://docs.oracle.com/javase/6/docs/api/java/util/TreeMap.html#TreeMap%28java.util.Comparator%29 के साथ पेड़ मानचित्र बनाया है, तो तुलनित्र का उपयोग किया जाता है)।

क्या गारंटी है इसलिए कि HashMap और HashSet में, विधि equals() वस्तुओं को अलग रखने का इस्तेमाल किया जाता है, और TreeMap में, विधि compareTo()

+0

यह वास्तव में बराबर विधि के कार्यान्वयन पर निर्भर करता है। आप वैसे भी बराबर विधि में संदर्भ द्वारा तुलना कर सकते हैं। – nhahtdh

+0

हैशकोड() विधि के बारे में कैसे। हालांकि बराबर सत्य वापस आते हैं और यदि हैशकोड() मान अलग हैं, फिर भी ये दो कुंजी समान हैं। –

+0

@ वल्लभपेटेड: 'हैशकोड' का अनुबंध: 'यदि दो वस्तुएं बराबर (ऑब्जेक्ट) विधि के बराबर होती हैं, तो दो ऑब्जेक्ट्स में हैशकोड विधि को कॉल करना एक ही पूर्णांक परिणाम उत्पन्न करना चाहिए।' आप तोड़ने के लिए स्वतंत्र हैं अनुबंध, लेकिन आवेदन पर निर्भर करता है कि यह टूट जाएगा। – nhahtdh

3

यदि आप खोलते हैं तो आप देख सकते हैं कि Object#equals विधि का उपयोग करके कुंजी और मान समीकरण की जांच की जाती है। वास्तव में मानचित्र के अंदर तुलना की जाएगी Object#equals विधि के कुंजी/मूल्य कार्यान्वयन पर निर्भर करता है।

0

यह वास्तव में K/Map के लिए निर्दिष्ट कुंजी के equals() कार्यान्वयन पर निर्भर करता है।

एक Map<Object,String> के साथ एक ही कर रही है की कोशिश करो और देखो क्या होता है:

चीयर्स

1

यहाँ पूर्णांक Waraper अंतिम वर्ग है (संकेत Object के लिए बराबर हो वे वास्तव में एक ही वस्तु होना है), जो equals() विधि अतिरंजित है, इसलिए यह केवल सामग्री की तुलना करेगा।

उपयोग पूर्णांकों कोई आवरण वर्ग वहाँ Map

में कोई समस्या नहीं मान लीजिए अगर आप कुंजी के रूप में Custome कक्षा का उपयोग आप Map

+1

से ऊपर मेरा संपादन देखें, आम तौर पर सच नहीं है, आप आसानी से एक अंतिम कक्षा प्राप्त कर सकते हैं जो 'बराबर() 'ओवरराइड करता है और फिर भी सामग्री समानता के बजाय ऑब्जेक्ट समानता पर परीक्षण करता है ... –

+0

इंटीजर क्लास अंतिम श्रेणी है, लेकिन इसमें केवल सामग्री compaered। इसका मतलब है कि हम व्यवहार को बदलने के लिए इस इंटीजर क्लास विधियों को ओवरराइड नहीं कर सकते हैं। – NPKR

+0

शायद आपको यह उल्लेख करना चाहिए कि मैप्स आमतौर पर चाबियों की समानता निर्धारित करने के लिए बराबर विधि को कॉल करते हैं - यही वह है जो मैं पूछ रहा था;) – Scolytus

0

में डुप्लिकेट से बचने के लिए equals() and hashcode() विधि ओवरराइड पहले दो अलग तुलना की जरूरत है चाहता हूँ कर रहे हैं तो अगर वस्तुओं (संदर्भ) -> झूठी।

दूसरा तुलना (बराबर) इन वस्तुओं के मूल्यों -> सच

HashMap अद्वितीय कुंजी निर्धारित करने के लिए बराबर और वस्तुओं की hascode तरीकों का उपयोग करता। इसलिए आपके पास एक ही कुंजी डाली गई है जिसके परिणामस्वरूप दो शेष तत्व हैं। दूसरा एक। क्या हो रहा है यह देखने के लिए Map#put javadoc पर एक नज़र डालें।

+0

यह वही नहीं है जो मैं पूछ रहा था, लेकिन जावाडोक ने मुझे एक सुराग दिया। महत्वपूर्ण हिस्सा है .containsKey() जहां इसे उपयोग करने के लिए निर्दिष्ट किया गया है .equals() – Scolytus

0

हैशैप के मामले में, चाबियों की तुलना बराबर() और हैशकोड() विधियों का उपयोग करके की जाती है।

उदाहरण के लिए, हैशकोड() और बराबर() दोनों और इंटीजर क्लास में ओवरराइड किया गया है। जब हैश मैप दो चाबियों की तुलना करता है, तो पहले उस ऑब्जेक्ट का हैशकोड() लेता है और फिर इस ऑब्जेक्ट पर समान विधि और उसी हैशकोड वाले कुंजी को कॉल करता है।

+0

यह मेरे प्रश्न का सही उत्तर नहीं है। – Scolytus

+0

मुझे बताएं कि मैं कहाँ स्पष्ट नहीं हूं? –

+0

यह मेरे प्रश्न का उत्तर नहीं है। लेकिन ऐसा लगता है कि मेरा प्रश्न समझना आसान नहीं है, हालांकि। (कम से कम लोगों को अंक नहीं मिलता है।) मेरा मुख्य हित इस सवाल के अंत में दो बुलेट बिंदु हैं जिन्हें किसी के द्वारा शायद ही उत्तर दिया जाता है। किसी भी तरह, सभी उत्तरों के योग के लिए धन्यवाद, मैंने इसे पहले से ही समझ लिया। सभी मानचित्र मुख्य तुलना के लिए बराबर() को कॉल करना चाहते हैं। शायद मैं इसे साफ करने के लिए सवाल संपादित करूंगा, मैंने सोचा कि अधिक संदर्भ अच्छा होगा ... – Scolytus

6

प्रश्न 1: - क्या यह गारंटी है कि मानचित्र या सेट जैसे संग्रह उनकी सामग्री से चाबियों की तुलना करेंगे, न कि उनके संदर्भ से?

ए 1: - नहीं संग्रह, मानचित्र और सेट इंटरफेस हैं। केवल एक चीज जिसे वे आश्वासन देते हैं वह संभावित तरीकों का अनुबंध है।

प्रश्न 2: - इसे वास्तविक कार्यान्वयन पर निर्भर करता है, जैसे हैश मैप?

ए 2: हां। तुलना के साथ कक्षा कैसे काम करती है यह एक डेवलपर निर्णय है।

HashMap उनकी वस्तुओं

पहले आवंटित करने के लिए दो बातें का उपयोग करें - Object#hashCode() है, कि सूचकांक की गणना करने के लिए किया जाता है।

दूसरा - Object#equals() है, जिसका उपयोग हैश कॉलिजन में होता है।

0

जब किसी आइटम को हैश मैप (और एक्सटेंशन द्वारा हैशसेट) के अंदर डालने के दौरान हैशकोड का उपयोग किया जाता है (यह निर्धारित करने के लिए एक सरल रैखिक फ़ंक्शन द्वारा परिवर्तित किया जाता है) यह निर्धारित करने के लिए कि आइटम को उसके आंतरिक संग्रह में कहां रखा जाना चाहिए।

फिर निर्धारित स्थान में यह (ओ 1 == o2 || o1.equals (o2)) का उपयोग करके एक समान वस्तु (वहां संग्रहीत सभी वस्तुओं के बीच) की खोज करता है, # संदर्भ फ़ंक्शन को संदर्भित किया जाता है, यदि संदर्भ भिन्न है सरल #equals कॉल में एक प्रदर्शन सुधार। यदि समान वस्तु पाई जाती है, तो उसके असाइन किए गए मान को नए के साथ बदल दिया जाता है, यदि नहीं, तो नया आइटम बस आंतरिक संग्रह में जोड़ा जाता है।