2011-07-29 13 views
8
public class Contact 
{ 
    int i; 
    String name; 
    public Contact(int iVal, String nameVal) 
    { 
     i = iVal; 
     name = nameVal; 
    } 
} 

public class MultiMap 
{ 
    public static void main (String args[]) 
    { 
     java.util.HashMap m = new java.util.HashMap(); 
       Contact m1 = new Contact(1, "name"); 
     Contact m2 = new Contact(1, "name"); 
     m.put(m1, "first"); 
     m.put(m2, "second"); 
     System.out.println(m.get(m1)); 
     System.out.println(m.get(m2)); 
    } 
} 

आउटपुट है:वस्तुओं और बराबर होती है

first 
second 

यह कैसे "मिल" विधि से व्यवहार करता है? चूंकि एम 1 और एम 2 दोनों के समान मूल्य हैं और मैंने हैशकोड() को ओवरराइड नहीं किया है, ऑब्जेक्ट क्लास के बराबर() विधि को कॉल किया जाएगा?

क्या यह सही है?

  1. कोई hashCode विधि तो वहाँ के लिए यदि वस्तुओं एम 1 और एम 2 अलग मान हैं JVM देखने के लिए
  2. कोई बराबर होती विधि इसलिए वर्ग के बराबर (वस्तु अधिरोहित) शुरू हो जाती है और कोई रास्ता नहीं है दोनों वस्तुओं के रूप में m1 के मान को प्रतिस्थापित करने के बिना एम 2 के बिना उपरोक्त कोड अलग-अलग काम करता है।

उत्तर

8

hashCode() और equals(Object o) तरीकों अपने वर्ग द्वारा ओवरराइड नहीं कर रहे हैं, जावा सिर्फ स्मृति में वस्तु के लिए वास्तविक संदर्भ का उपयोग करता मूल्यों की गणना करने (यानी। जाँच अगर यह वर्ग का एक ही इन्स्टेन्शियशन है)। यही कारण है कि आप अभी भी दोनों परिणाम प्राप्त करते हैं।

0

यहाँ Contact क्लास में hashcode() और equals() कार्यों को लागू नहीं किया।

जब हैश मैप इन तरीकों को कॉल करता है तो यह इस विधि के लिए मूल वर्ग में इस विधि के लिए खोज करेगा जो इस मामले में ऑब्जेक्ट है।

इस मामले में हीप पर ऑब्जेक्ट स्थान मानों के बजाय मूल्यांकन किया जाता है।

उदा। दो वस्तुओं o1 और o2

o1.equals(o2) == true के लिए केवल जब o1 == o2

hashCode() वस्तु वर्ग का एक तरीका है। हैश कोड JVM द्वारा ऑब्जेक्ट का एक पूर्णांक प्रतिनिधित्व है। हैश कोड सिस्टम जेनरेट किया गया है और जेवीएम हैश कोड उत्पन्न करने के लिए ऑब्जेक्ट का पता आधार (बीज) के रूप में लेता है। उत्पन्न किए गए हैश कोड निष्पादन के विभिन्न समय के लिए समान नहीं होना चाहिए।

0

हाँ यह सही है। कोई भी जावा ऑब्जेक्ट जो अपने स्वयं के बराबर और हैशकोड विधियों को परिभाषित नहीं करता है, java.lang.Object पर डिफ़ॉल्ट बराबर और हैकोड विधियों का उत्तराधिकारी है। ये डिफ़ॉल्ट कार्यान्वयन वस्तु संदर्भ समानता पर आधारित है और तर्कसंगत समानता पर नहीं। चूंकि आपने उसी ऑब्जेक्ट संदर्भ के साथ कॉल किया है, इसलिए वस्तु को मानचित्र से वापस किया जा सकता है।

यहां एक उदाहरण है जो इसे आगे बढ़ाता है।

java.util.HashMap m = new java.util.HashMap(); 
Contact m1 = new Contact(1, "name"); 
Contact m2 = new Contact(1, "name"); 
m.put(m1, "first"); 
m.put(m2, "second"); 
System.out.println(m.get(m1));//first 
System.out.println(m.get(m2));//second 
System.out.println(m.get(new Contact(1, "name"));//null - since the new object has a different object reference. 
0

हालांकि एम 1 और एम 2 के समान मूल्य हैं, वे अलग-अलग ऑब्जेक्ट संदर्भ हैं।

यह सही है: तो वहाँ कोई रास्ता नहीं के लिए यदि वस्तुओं एम 1 और m2 अलग मान हैं JVM को देखने के लिए है कोई hashCode विधि है -> तो यह hashCode मूल्य की गणना करने वस्तु वर्ग के hasCode() विधि का उपयोग करता है get() को निष्पादित करने के लिए, जो विभिन्न हैश मान (स्पष्ट) लौटाता है।

दूसरी बात भी सही है: आप अपने खुद के बराबर(), लागू नहीं किया है के रूप में वस्तु की बराबरी पर विचार करेंगे() जो सच केवल जब एक वस्तु ही की तुलना में है देता है।

2

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

  1. हाँ, जावा हमेशा देखेंगे दो संपर्क वस्तुओं अलग रूप में यह जब यह संदर्भ के लिए है वस्तु
  2. हाँ में बराबर पद्धति का उपयोग करके, दो संपर्क वस्तुओं के रूप में तुलना करने के लिए ऑब्जेक्ट संदर्भ का उपयोग करेगा कर रहे हैं।
3

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

तुलना के लिए, पहचान हैशैप हमेशा ऐसा करता है भले ही आपने हैशकोड और बराबर को ओवरराइड किया हो।

0

डिफ़ॉल्ट रूप से ऑब्जेक्ट क्लास हैशकोड को ओवरराइड करता है और विधि के बराबर होता है। वांछित आउटपुट प्राप्त करने का यही कारण है।

यदि आप बराबर और हैशकोड विधि को ओवरराइड नहीं करते हैं, तो JVM दृश्य के पीछे इसे जांचता है। चूंकि एम 1 और एम 2 दोनों अलग-अलग ऑब्जेक्ट उदाहरण हैं, समान विधि हमेशा झूठी वापसी करती है। यानी:

1. बराबरी के लिए: क्योंकि दोनों अलग अलग उदाहरण हैं

m1.equals (एम 2) रिटर्न फाल्स //।

2. hashCode के लिए: // HashMap.java अंदर स्रोत कोड देखें

HashMap आंतरिक HashMap में डालने से पहले कुंजी मिश्रित उपयोग करता है। नीचे देखें।

[![Source code of put method][1]][1] 
public V put(K key, V value) { 
    return putVal(hash(key), key, value, false, true); 
} 
मिलावत के लिए

, HashMap यह खुद स्थिर हैश विधि है है:

[![Source code of hash method][1]][1] 
static final int hash(Object key) { 
     int h; 
     return (key == null) ? 0 : (h = key.hashCode())^(h >>> 16); 
    } 

आंतरिक रूप से, दोनों बराबर और hashCode विधि इस तरह से काम करते हैं, यही वजह है कि आप दोनों मिल मूल्यों HashMap में संग्रहीत ।

उम्मीद है कि यह मदद करता है :)

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