2013-03-28 38 views
5

में मशीनों में जावा और string.hashCode() स्थिरता। मैंने similar question को string.GetHashCode() विधि .NET में विधि के लिए कहा है। तब से, मैंने सीखा है कि हम बुटी-इन प्रकारों के लिए हैश कोड के निहित कार्यान्वयन पर भरोसा नहीं कर सकते हैं, अगर हम इसे विभिन्न मशीनों में उपयोग करना चाहते हैं। इसलिए, मैं यह सोचते हैं हूँ String.hashCode() के जावा कार्यान्वयन भी अलग हार्डवेयर विन्यास भर में अस्थिर है और VMs भर में अलग तरीके से व्यवहार कर सकते हैं (विभिन्न वीएम कार्यान्वयन मत भूलना)क्लस्टर

वर्तमान में हम सुरक्षित रूप से एक में एक स्ट्रिंग को बदलने के लिए एक तरह से चर्चा कर रहे हैं कि हैशिंग द्वारा जावा में संख्या, लेकिन हैश एल्गोरिदम क्लस्टर के विभिन्न नोड्स में स्थिर होना चाहिए, और मूल्यांकन करने के लिए तेज़ होना चाहिए, क्योंकि उपयोग की उच्च आवृत्ति होगी। मेरी टीम के साथी मूल hashCode विधि पर जोर दे रहे हैं, और मुझे एक और दृष्टिकोण पर पुनर्विचार करने के लिए कुछ उचित तर्कों की आवश्यकता होगी। वर्तमान में, मैं केवल मशीन कॉन्फ़िगरेशन (x86 और x64) के बीच मतभेदों के बारे में सोच सकता हूं, संभवतः मशीनों के आधार पर मशीनों के आधार पर कुछ मशीनों (शायद हमारे मामले में लागू) और बाइट-ऑर्डर मतभेदों पर JVM के विभिन्न विक्रेताओं के बारे में सोच सकते हैं, एल्गोरिदम मशीन पर निर्भर करता है चलाते हैं। बेशक, चरित्र एन्कोडिंग शायद भी माना जा सकता है।

हालांकि ये सभी चीजें मेरे दिमाग में आती हैं, मैं उनमें से किसी एक में पर्याप्त कारण होने के लिए 100% निश्चित नहीं हूं, और मैं इस क्षेत्र में आपकी विशेषज्ञता और अनुभव की सराहना करता हूं। इससे मुझे एक कस्टम हैशिंग एल्गोरिदम लिखने के पक्ष में मजबूत तर्क बनाने में मदद मिलेगी। इसके अलावा, मैं पर सलाह देने पर सलाह देता हूं कि इसे लागू करते समय क्या करें।

+1

स्ट्रिंग हैशकोड किसी भी जावा प्लेटफॉर्म पर अच्छी तरह से परिभाषित और समान है। – ZhongYu

+1

http://stackoverflow.com/questions/785091/consistency-of-hashcode-on-a-java-string – zch

+0

@ zhong.j.yu आप मान रहे हैं [JRockit] (http://www.oracle.com /technetwork/middleware/jrockit/overview/index.html) और [आईबीएम जेवीएम] (http://publib.boulder.ibm।com/infocenter/java7sdk/v7r0/index.jsp? topic =% 2Fcom.ibm.java.lnx.70.doc% 2 फ़्यूसर% 2Fjava_jvm.html) के पास स्ट्रिंग # हैशकोड' के लिए समान कार्यान्वयन है। –

उत्तर

11

String.hashCode() के कार्यान्वयन दस्तावेज में specified है, इसलिए यह लगातार होने की गारंटी है:

स्ट्रिंग ऑब्जेक्ट के लिए हैश कोड

s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] 

के रूप में गणना की जाती है पूर्णांक गणित, जहां s का उपयोग करके [i] स्ट्रिंग का ith चरित्र है, n स्ट्रिंग की लंबाई है, और^एक्सपोनेंटिएशन इंगित करता है। (खाली स्ट्रिंग का हैश मान शून्य है।)

उन सभी कार्यों को जावा के लिए स्वतंत्र रूप से मंच-कार्यान्वित किया जाता है - उदाहरण के लिए प्लेटफार्म बाइट ऑर्डर अप्रासंगिक है।

उस ने कहा, String प्राप्त करने के तरीके मुश्किल हो सकते हैं, अगर आप इसे किसी फ़ाइल या बाइट्स के अन्य स्रोत से प्राप्त कर रहे हैं। उस स्थिति में, आप ठीक से ठीक हैं जब आप स्पष्ट रूप से Charset निर्दिष्ट करते हैं। (याद रखें कि String अलग एन्कोडिंग से प्रति नहीं है; कोई एन्कोडिंग रूपांतरण एक byte[] और एक String के बीच के लिए एक विनिर्देश है।)

+0

जहां तक ​​सभी विनिर्देशन (और मूल जावा घटक मुझे पता है) द्वारा चला जाता है, यह वास्तव में पर्याप्त सुरक्षित लगता है। धन्यवाद –

3

आप sourcecode, also shown below देख सकते हैं। जो मैं देख सकता हूं (विश्लेषण के 10 सेकंड के बाद) यह मशीनों और आर्किटेक्चर में स्थिर होना चाहिए। और लुई एक spec उद्धृत करके यह पुष्टि करता है, भले ही आप चश्मे पर विश्वास करते हैं। :-)

हालांकि, यह भिन्न हो सकता है यदि एक अलग जेआरई इसे अलग-अलग लागू करने और spec का उल्लंघन करने का विकल्प चुनता है।

public int hashCode() { 
    int h = hash; 
    if (h == 0) { 
     int off = offset; 
     char val[] = value; 
     int len = count; 

     for (int i = 0; i < len; i++) { 
      h = 31*h + val[off++]; 
     } 

     hash = h; 
    } 

    return h; 
} 
+0

आपके उत्तर के लिए धन्यवाद। मैंने खुद को सोर्स कोड देखा है और मुझे कुछ भी नहीं मिला जो कोई मुद्दा हो सकता है। फिर भी, कुछ मुझे बताता है कि यह एकमात्र ऐसा स्थान नहीं है जहां चीजें गलत हो सकती हैं। उम्मीद है कि, एक ही क्लस्टर में विभिन्न जेवीएम (विभिन्न विक्रेताओं) हमारे लिए एक मामला नहीं होगा। –

+1

मुझे लगता है कि यदि कोई विक्रेता स्पेक तोड़ रहा है तो आप ज्ञात स्ट्रिंग्स का एक गुच्छा चला सकते हैं और आधिकारिक परिणामों की तुलना कर सकते हैं। कुछ _long_ वाले चलाने के लिए सुनिश्चित हो। जावा के प्रारंभिक दिनों में वापस हैशकोड विधि केवल पहले 16 (शायद 32?) वर्णों को माना जाता है। मैं वही कर कर एक बेंचमार्क जीतने की कोशिश कर रहा एक विक्रेता देख सकता था। – user949300

+0

अच्छी सलाह, इसे साझा करने के लिए धन्यवाद। मैं वर्तमान मामले के लिए विश्वास करता हूं कि हम ओरेकल के जेवीएम के साथ रहेंगे, हालांकि ज्ञान एक दिन काफी उपयोगी साबित हो सकता है। इस पर विचार रखने के कारण, इस तरह के "प्रदर्शन लाभ" के लिए बहुत अवांछित और अप्रत्याशित व्यवहार हो सकता है। आश्चर्य है कि अगर एक जेवीएम विक्रेता उस श्रेणी में गिर सकता है –

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