2012-03-19 11 views
6

मुझे आश्चर्य है कि जावा के Hashtable#hashCode() का डिफ़ॉल्ट कार्यान्वयन टूट गया है जब Hashtable में प्रति जोड़े समान कुंजी और मान वाली प्रविष्टियां होती हैं।जावा हैशटेबल # हैशकोड() कार्यान्वयन टूटा हुआ है?

उदाहरण के लिए देखें निम्न अनुप्रयोग:

public class HashtableHash { 
    public static void main(final String[] args) { 
     final Hashtable<String, String> ht = new Hashtable<String, String>(); 

     final int h1 = ht.hashCode(); 
     System.out.println(h1); // output is 0 

     ht.put("Test", "Test"); 

     final int h2 = ht.hashCode(); 
     System.out.println(h2); // output is 0 ?!? 

     // Hashtable#hashCode() uses this algorithm to calculate hash code 
     // of every element: 
     // 
     // h += e.key.hashCode()^e.value.hashCode() 
     // 
     // The result of XOR on identical hash codes is always 0 
     // (because all bits are equal) 

     ht.put("Test2", "Hello world"); 

     final int h3 = ht.hashCode(); 
     System.out.println(h3); // output is some hash code 
    } 
} 

एक खाली Hashtable के लिए हैश कोड 0. कुंजी "Test" और मूल्य "Test" के साथ एक प्रविष्टि के बाद Hastable को अभी भी हैश कोड जोड़ दिया गया है है है 0.

समस्या Hashtable के hashCode() विधि में प्रत्येक प्रविष्टि के हैश कोड गणना की और हैश कोड में जोड़ा जाता है कि के रूप में

इस प्रकार है
h += e.key.hashCode()^e.value.hashCode() 

हालांकि समान हैश कोड (जो समान स्ट्रिंग्स का मामला है) पर XOR हमेशा 0 है। इसलिए समान कुंजी और मान वाली प्रविष्टियां हैशटेबल के हैश कोड का हिस्सा नहीं हैं।

यह कार्यान्वयन imho टूटा हुआ है क्योंकि वास्तव में हैशटेबल बदल गया है। इससे कोई फर्क नहीं पड़ता कि कुंजी और मूल्य समान हैं या नहीं।

+2

मुझे आश्चर्य है कि यह क्यों कम किया गया था क्योंकि यह एक कानूनी सवाल है और किसी को कुछ परेशानी बचा सकता है। मैं इस व्यवहार के कारण होने वाली एक बग खोजने के लिए घंटों की तलाश कर रहा हूं। –

+2

आप * एक अलग हैशकोड पर भरोसा नहीं कर सकते क्योंकि सिर्फ वस्तु अलग है। क्या आप कहेंगे कि हैशकोड भी टूटा हुआ है यदि मैं दो पूरी तरह से अलग वस्तुओं को जोड़ता हूं और हैशकोड भी रहता है? उस स्थिति में यदि संभव वस्तुओं का ब्रह्मांड 2^32 .. – Voo

+0

से बड़ा है तो यह संभव है कि प्रत्येक संभावित हैशकोड कार्यान्वयन टूट गया है। यह एक प्रश्न से अधिक अवलोकन है। (हालांकि मेरा डाउनवोट नहीं है।) –

उत्तर

6

hashCode पर प्रलेखन से;

यह है नहीं आवश्यक है, तो दो वस्तुओं विधि बराबर (java.lang.Object) के अनुसार असमान हैं, तो बुला कि दो वस्तुओं में से प्रत्येक पर hashCode विधि अलग पूर्णांक परिणाम का उत्पादन होगा। हालांकि, प्रोग्रामर को पता होना चाहिए कि असमान वस्तुओं के लिए अलग पूर्णांक परिणाम उत्पन्न करने से हैशटेबल्स के प्रदर्शन में सुधार हो सकता है।

दूसरे शब्दों में, खराब कार्यान्वयन - शायद। टूटा - कल्पना के अनुसार नहीं।

5

यह टूटा नहीं है, यह डिज़ाइन और विज्ञापित के रूप में काम कर रहा है। हैश कोड दो Map के बराबर होने के लिए दो Map बराबर होने की आवश्यकता नहीं है।

1

hashCode की एकमात्र आवश्यकता यह है कि यदि दो ऑब्जेक्ट बराबर हैं, तो उनके हैश कोड बराबर होना चाहिए। इस प्रकार

public int hashCode() { 
    return 123; 
} 

पूरी तरह मान्य है, हालांकि इष्टतम नहीं है।