एक मामले में जहां hashcodes का उपयोग कर के रूप में समानता तुलना पर एक छोटी-कट समझ में आता है नहीं है।
मामले ऐसे हैं जिनमें एक hashtable या HashSet निर्माण कर रहे हैं पर विचार करें। वास्तव में, आइए बस हैशसेट्स पर विचार करें (हैशटेबल्स का विस्तार भी एक मूल्य धारण करके, लेकिन यह प्रासंगिक नहीं है)।
कई अलग-अलग दृष्टिकोण हैं जो कोई भी ले सकते हैं, लेकिन उनमें से सभी में आपके पास ढेर मूल्यों की एक छोटी संख्या है, और हम या तो खुले या बंद दृष्टिकोण (जो सिर्फ मस्ती के लिए, कुछ लोग दूसरों के लिए विपरीत शब्दकोष का उपयोग करें); अगर हम दो अलग-अलग वस्तुओं के लिए एक ही स्लॉट पर टकराते हैं तो हम उन्हें एक ही स्लॉट में स्टोर कर सकते हैं (लेकिन एक लिंक की गई सूची या ऐसी वस्तुओं के लिए जहां वस्तुओं को वास्तव में संग्रहीत किया जाता है) या एक अलग स्लॉट लेने के लिए फिर से जांच करके (विभिन्न हैं इसके लिए रणनीतियों)।
अब, या तो दृष्टिकोण के साथ, हम दूर हे (1) जटिलता हम एक hashtable साथ चाहते से जा रहे हैं, और एक हे (एन) जटिलता की ओर। इसका जोखिम उपलब्ध स्लॉट की संख्या के विपरीत आनुपातिक है, इसलिए एक निश्चित आकार के बाद हम हैशटेबल का आकार बदलते हैं (भले ही सबकुछ आदर्श था, हमें अंततः यह करना होगा यदि संग्रहित वस्तुओं की संख्या से अधिक थी स्लॉट्स)।
फिर से डालने एक आकार बदलने पर आइटम हैश कोड पर निर्भर स्पष्ट रूप से होगा। इस वजह से, यह किसी ऑब्जेक्ट में GetHashCode()
को याद करने के लिए शायद ही कभी समझ में आता है (इसे अक्सर अधिकांश ऑब्जेक्ट्स पर पर्याप्त नहीं कहा जाता है), यह निश्चित रूप से हैश टेबल के भीतर इसे याद करने के लिए समझ में आता है (या शायद, उत्पादित को याद करने के लिए नतीजतन, जैसे कि यदि आप खराब GetHashCode()
कार्यान्वयन के कारण होने वाले नुकसान को कम करने के लिए एक वैंग/जेनकिन्स हैश के साथ फिर से धोया गया है)। वस्तु के लिए हैश कोड प्राप्त करें
- :
अब, जब हम अपने तर्क डालने के लिए आते हैं की तरह कुछ होने जा रहा है।
- ऑब्जेक्ट के लिए स्लॉट प्राप्त करें।
- यदि स्लॉट खाली है, तो उसमें ऑब्जेक्ट रखें और वापस आएं।
- यदि स्लॉट में समान वस्तु है, तो हम हैशसेट के लिए किए गए हैं और हैशटेबल के लिए मान को प्रतिस्थापित करने की स्थिति है। ऐसा करो, और वापस आओ।
- टक्कर रणनीति के अनुसार अगले स्लॉट का प्रयास करें, और आइटम 3 पर वापस आएं (शायद यह आकार बदलना अगर हम इसे अक्सर लूप करते हैं)।
तो, इस मामले में हमें समानता की तुलना करने से पहले हैश कोड प्राप्त करना होगा। हमारे पास आकार बदलने की अनुमति देने के लिए पहले से गणना की गई मौजूदा वस्तुओं के लिए हैश कोड भी है। इन दोनों तथ्यों के संयोजन मतलब है कि यह समझ में आता है के रूप में आइटम 4 के लिए हमारे तुलना लागू करने के लिए:
private bool IsMatch(KeyType newItem, KeyType storedItem, int newHash, int oldHash)
{
return ReferenceEquals(newItem, storedItem) // fast, false negatives, no false positives (only applicable to reference types)
||
(
newHash == oldHash // fast, false positives, no fast negatives
&&
_cmp.Equals(newItem, storedItem) // slow for some types, but always correct result.
);
}
जाहिर है, इस का लाभ _cmp.Equals
की जटिलता पर निर्भर करता है। यदि हमारा मुख्य प्रकार int
था तो यह कुल अपशिष्ट होगा। यदि हमारे मुख्य प्रकार जहां स्ट्रिंग और हम केस-असंवेदनशील यूनिकोड-सामान्यीकृत समानता तुलना का उपयोग कर रहे थे (इसलिए यह लंबाई पर भी शॉर्टकट नहीं कर सकता) तो बचत अच्छी तरह से लायक हो सकती है।
आम तौर पर याद रखने वाले हैश कोड को समझ में नहीं आता है क्योंकि उन्हें अक्सर प्रदर्शन जीतने के लिए पर्याप्त उपयोग नहीं किया जाता है, लेकिन हैशसेट या हैशटेबल में उन्हें संग्रहीत करना स्वयं समझ सकता है।
एक डेवलपर के रूप में, आप इसे अपने आप को देना है पूरी तरह से समझने के लिए क्या कर रहे हैं हैश के लिए उपयोग किया जाता है और कैसे वे हैश तालिकाओं से संबंधित हैं (जैसा कि शब्दकोश और हैशसेट द्वारा कार्यान्वित किया गया है)। हैशटेबल के लिए विकिपीडिया आलेख एक अच्छी शुरुआत है: http://en.wikipedia.org/wiki/Hash_table – spender
@ स्पेंडर - यह वही है जो इस प्रश्न ने मुझे मूल रूप से समझने या दिमाग में कॉल करने से अधिक विस्तार से समझाया है। – Armbrat
समानता जांच गलत नहीं है, कोड अजीब है। आप 397 से शून्य गुणा क्यों कर रहे हैं? मैं अभी आपको बता सकता हूं, जवाब शून्य होने जा रहा है, तो मशीन को इसकी गणना क्यों करें? एक मूल्य के साथ xor शून्य क्यों; यह एक पहचान ऑपरेशन है। –