(l >> 32)^l
ज्यादातर मामलों में एक अच्छा हैशकोड है; खासकर जब लंबे समय तक एक समान वितरण होता है।
चूंकि यह स्वीकार्य उत्तर था, इसलिए मैं अपनी कुछ टिप्पणियों को स्पष्ट करने के लिए इसे पोस्ट कर रहा हूं कि यह लंबे समय तक एक अच्छा हैशकोड नहीं है।
public class Point {
private final long coords; //x in high-bits, y in low
public int getX() {
return (int)(coords >> 32);
}
public int getY() {
return (int)coords;
}
public int hashCode() {
return (int)((coords >> 32)^(coords));
}
}
यह काल्पनिक लग सकता है, लेकिन कभी कभी आप एक लंबे में पैक एकाधिक "फील्ड" है:
उदाहरण मैं दे दी है इस तरह एक प्वाइंट वर्ग था।
तो coords
फ़ील्ड x के 32 बिट्स और 32 बिट्स वाई का प्रतिनिधित्व करता है। तो यह एक समस्या क्यों है? खैर, ऐसा नहीं है कि प्रत्येक एक्स और वाई को उनके संबंधित 32 बिट्स पर समान रूप से वितरित किया जाता है। लेकिन यह अभ्यास में असंभव है। अधिक संभावना है कि एक्स और वाई कुछ संख्या से बंधे हैं। आइए 1024 कहें क्योंकि यह 2^10 है। इसका मतलब है कि अधिक से अधिक प्रत्येक एक्स और वाई के निचले 10 बिट सेट कर रहे हैं:
00000000 00000000 000000XX XXXXXXXX 00000000 00000000 000000YY YYYYYYYY
2^20 (1024 * 1024) संभव संयोजनों रहे हैं। लेकिन ऑपरेशन हैशकोड क्या कर रहा है?
00000000 00000000 000000XX XXXXXXXX
^ 00000000 00000000 000000YY YYYYYYYY
-------------------------------------
= 00000000 00000000 000000?? ????????
पर सबसे 2^10 (1024) संभव hashCode मूल्यों के बाद से ही कम 10 बिट कभी शून्य के अलावा कुछ भी हो सकता हैं। हैश मानों का वास्तविक मूल्यों का अनुपात 1024:(1024*1024)
या 1:1024
है। तो बल्ले से बाहर एक 1/1024 संभावना है कि दो संख्याओं में एक ही हैश है।
अब birthday problem से गणित लागू करके टकराव की संभावना की गणना करें। पी (एन) को संभावना है कि एन मानों के साथ कम से कम एक टकराव होगा। हम जानते हैं कि पी (1025+) = 1 क्योंकि केवल 1024 मान हैं।
p(n) = 1 - (n! * (1024 choose n))/1024^n
यह निम्न करने के लिए बाहर काम करता है:
n: p(n)
1: 0.00000
2: 0.00098
3: 0.00293
4: 0.00585
5: 0.00973
6: 0.01457
...
38: 0.50096
...
79: 0.95444
...
148: 0.99999
सिर्फ 38 आइटम के साथ
, वहाँ शायद एक टक्कर है। 148 वस्तुओं के साथ, 99.9 99% मौका (कम से कम एक) टक्कर है। 148 वस्तुओं के साथ, प्रत्येक आइटम में किसी अन्य आइटम के साथ टकराने का 7% मौका होता है। उचित हैशिंग फ़ंक्शन के साथ, डोमेन का ज्ञान लेते हुए, ये संख्या आसानी से 0
दूसरे शब्दों में, अपने डोमेन को जानना और अभ्यास में चीजें कैसे होती हैं, एक कलाकार हैश बनाने की कुंजी होती है।लाइब्रेरी फ़ंक्शन आपके डोमेन के बारे में कुछ भी नहीं जानते जितना संभव हो उतना अच्छा काम करने की कोशिश करते हैं, और कलाकार होने के लिए आमतौर पर डेटा के वितरण पर भरोसा करते हैं जो अभ्यास में नहीं होगा।
बीटीडब्ल्यू अगर आप केवल 32 बिट्स रखना चाहते हैं, तो मॉड्यूलो ऑपरेशन की कोई आवश्यकता नहीं है। 'Int' पर कास्टिंग पर्याप्त है: 'int हैशकोड = (int) id'। – Grodriguez
@Grodriguez क्षमा करें, लेकिन यह जवाब भयानक है! इससे कई ऑब्जेक्ट्स एक ही हैशकोड हो जाएंगे जो हैश टकराव के सभी प्रकार बनाएगा। आप हमेशा समान रूप से वितरित हैश कोड चाहते हैं। इसके अलावा स्वीकृत उत्तर सबसे अच्छा समाधान नहीं है, क्योंकि जावा 8 ने एक बेहतर समाधान पेश किया था। कृपया "नाथन" द्वारा दिए गए उत्तर का संदर्भ लें, क्योंकि 'Long.hashcode (long)' स्टैक –
@Neuron पर कोई नई ऑब्जेक्ट नहीं बनाता है कोई भी हैश फ़ंक्शन जो 32 बिट एक में 64 बिट मान को मानचित्र करता है "कारण कई ऑब्जेक्ट एक ही हैशकोड "। इससे बचने के लिए कोई रास्ता नहीं है। इसके अलावा, इस बात की कोई गारंटी नहीं है कि '(this.longValue()^(this.longValue() >>> 32))' मूल्य के निचले 32 बिट्स को रखने के बजाय 'समान रूप से वितरित हैश कोड उत्पन्न करता है। – Grodriguez