2009-06-30 15 views
10

पर आधारित जावा हैशकोड ऑब्जेक्ट.hashCode() का डिफ़ॉल्ट व्यवहार वस्तु के "पता" को अनिवार्य रूप से वापस करना है ताकि aHashCode() == b.hashCode() अगर और केवल अगर एक == बी । यदि सुपरक्लस पहले से ही हैशकोड() को परिभाषित करता है तो मैं इस व्यवहार को उपयोगकर्ता द्वारा परिभाषित कक्षा में कैसे प्राप्त कर सकता हूं? उदाहरण के लिए:पहचान

class A { 
    public int hashCode() { 
    return 0; 
    } 
} 

class B extends A { 
    public int hashCode() { 
    // Now I want to return a unique hashcode for each object. 
    // In pythonic terms, it'd look something like: 
    return Object.hashCode(this); 
    } 
} 

विचार?

+1

नहीं, यह नहीं है। यह कोड प्राप्त करना है ताकि aHashCode()! = B.hashCode() जरूरी है कि एक! = बी। –

+3

... लेकिन a.hashCode() == b.hashCode() का मतलब नहीं है == बी मुझे जोड़ा जाना चाहिए था। –

+1

यदि "a.equals (b)", जरूरी नहीं है "a == b", तो हैश कोड बराबर होना चाहिए: "a.hashCode() == b.hashCode()" –

उत्तर

25

System.identityHashCode(Object) इस व्यवहार को प्रदान करता है।

आप इस बारे में होगा:

class B extends A { 
    public int hashCode() { 
    return System.identityHashCode(this); 
    } 
} 

की जांच करें बराबर-विधि, कि यह केवल सच देता है, अगर दो वस्तुओं एक ही हैं। अन्यथा यह equals और hashCode के लिए वर्णित व्यवहार को तोड़ देगा। (सही होने के लिए, बराबर-विधि झूठी वापस जाने के लिए, यदि आप दो वस्तुओं के लिए अलग hashcodes मिलता है।)) बराबरी के एक कार्यान्वयन (जो दिए गए hashCode का अनुपालन प्रदान करने के लिए() - विधि:

public boolean equals(Object other){ 
    return this == other; 
} 
9

System.identityHashCode() का प्रयोग करें। यह IdentityHashMap उपयोग करता है।

आप अत्यंत इस के साथ एक मौजूदा hashCode() अधिभावी हालांकि क्योंकि आप hashCode अनुबंध तोड़ सकता, किया जा रहा से सावधान रहना चाहिए कि दो वस्तुओं है कि:

अगर a.equals (ख) तो a.hashCode() बराबर होना चाहिए b.hashCode()

आप मौजूदा व्यवहार को ओवरराइड करके इसे तोड़ सकते हैं या आपको बराबर() भी ओवरराइड करने की आवश्यकता हो सकती है।

1

जैसा कि मन्मेन्थ ने कहा था, मैं बस यह इंगित करना चाहता हूं कि हैशकोड() 0 (या कोई निरंतर मान) लौटा रहा है (जबकि लंगड़ा)। हैशकोड() कर सकते हैं (और चाहिए) केवल ए और बी के लिए अलग-अलग मान वापस कर सकते हैं! a.equals (बी)।
इसलिए उदाहरण के लिए आप

class A { 
    public int hashCode() { 
    return 0; 
    } 
    public boolean equals(Object o) { 
    return o instanceof A; // all objects are equal 
    } 
} 

class B extends A { 
    public int hashCode() { 
    return System.identityHashCode(this); 
    } 
    public boolean equals(Object o) { 
    return this.hashCode().equals(o.hashCode()); 
    } 
} 

अब आपके पास दो वस्तुओं को बनाने के लिए है:

A a = new A(); 
A b = new B(); 

और अचानक a.equals (ख), लेकिन b.equals (क)। बेशक अधिक वास्तविक जीवन में ए में बराबर() अधिक परिष्कृत होगा, लेकिन समस्या अभी भी बनी हुई है। इस समस्या से छुटकारा पाने के लिए आप हमेशा

if (super.equals(o)) return true; 

नए बराबर() की शुरुआत में हमेशा कॉल करना चाहते हैं।

और हैशकोड() को ओवरराइड करने के बाद सख्ती से बराबर है(), आप यह सुनिश्चित करना चाहते हैं कि हर जगह सुपर.क्वल्स() किसी भी दो दिए गए ऑब्जेक्ट्स के लिए सच हो जाए, नया हैशकोड() सुपर.hashCode() वापस कर देगा ।

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