2012-07-22 7 views
27

ठीक है, तो जावा 7 में हमारे पासObjects.hash() बनाम Objects.hashCode(), स्पष्टीकरण की जरूरत

o.hashCode(); 
    Objects.hashCode(o); 

    Objects.hash(o); 

पहले 2 मोटे तौर पर अशक्त बिंदु की जांच के साथ एक ही हैं, लेकिन क्या पिछले एक है ?

जब एक ऑब्जेक्ट संदर्भ प्रदान किया जाता है, तो लौटाया गया मान उस ऑब्जेक्ट संदर्भ के हैश कोड के बराबर नहीं है।

वह क्यों है? मेरा मतलब है, हमें 3 तरीकों की आवश्यकता नहीं है जो एक ही काम करते हैं, मैं समझता हूं .. लेकिन हमें Objects.hash() क्यों चाहिए? आप एक बनाम दूसरे का उपयोग करने के लिए कब चुना होगा?

उत्तर

47

hashCode और hash के लिए प्रलेखन देखें। hashObject... लेता है जबकि hashCodeObject लेता है। उदाहरण दिया है:

@Override public int hashCode() { 
    return Objects.hash(x, y, z); 
} 
  • Objects.hash(Object... values) मामलों में इस्तेमाल किया जाना चाहिए जब आप वस्तुओं की एक अनुक्रम, उदा के हैश चाहते अपने hashCode विधि को परिभाषित करते समय और अपने ऑब्जेक्ट की पहचान करने वाले कई मानों के लिए एक कोड-कोडित हैश चाहते हैं।
  • Objects.hashCode(Object o) का उपयोग तब किया जाना चाहिए जब आप एक ऑब्जेक्ट का हैश चाहते हैं, ऑब्जेक्ट शून्य होने पर फेंकने के बिना।
  • Object::hashCode() का उपयोग तब किया जाना चाहिए जब आप एक ऑब्जेक्ट का हैश चाहते हैं, और ऑब्जेक्ट शून्य होने पर अपवाद फेंक देगा।

ध्यान दें कि hash(o) और hashCode(o) आवश्यक नहीं होगा एक ही चीज़! यदि आप इसे एक ऑब्जेक्ट के लिए कर रहे हैं, तो आपको शायद hashCode का उपयोग करना चाहिए।

+0

किस स्थिति में 'हैश (ओ) 'और' हैशकोड (ओ) 'वही मूल्य वापस नहीं करेगा? 'हैश()' राज्य 'के लिए दस्तावेज़ चेतावनी: जब एक ऑब्जेक्ट संदर्भ प्रदान किया जाता है, तो लौटाया गया मान उस ऑब्जेक्ट संदर्भ के हैश कोड के बराबर नहीं होता है।', लेकिन मैं अभी भी यह पता लगाने के लिए खुदाई कर रहा हूं कि क्यों। –

7

ऑब्जेक्ट का डिफ़ॉल्ट हैशकोड() वस्तु के लिए स्मृति पता देता है। तो अगर आप निम्नलिखित वर्ग है:

class Car { 
    String make; 
    String model; 
    int year; 

    public Car(String make, String model, int year) { 
     this.make = make; 
     this.model = model; 
     this.year = year; 
    } 
} 

तो दो वस्तुओं को बनाने:

Car car1 = new Car("Toyota", "Corolla", 2010); 
Car car2 = new Car("Toyota", "Corolla", 2010); 

car1.hashCode() car2.hashCode() से अलग होगा क्योंकि प्रत्येक वस्तु एक अलग स्मृति पता होगा ।

क्या होगा यदि आप कार 1 और कार 2 दोनों को एक ही हैश कोड वापस करने के लिए चाहते हैं? इस मामले में, आप के रूप में इस कार वर्ग के लिए डिफ़ॉल्ट वस्तु hashCode() विधि ओवरराइड करना चाहिए:

@Override 
public int hashCode() { 
    Object[] x = {model, make, Integer.valueOf(year)}; 
    int hashArray = Arrays.hashCode(x); 
    return hashArray; 
} 

यह car1.hashCode() car2.hashCode() क्योंकि String.hashCode के बराबर कर देगा() स्ट्रिंग सामग्री के आधार पर हैशकोड की गणना करता है, और Integer.hashCode() पूर्णांक मान को वापस कर देगा।

जावा 7 में, आप केवल ऑब्जेक्ट्स.hash (ऑब्जेक्ट ... मान) का उपयोग कर सकते हैं।

@Override 
public int hashCode() { 
    return Objects.hash(model, make, year); 
} 

Objects.hash (वस्तु ... मान) आप के लिए Arrays.hashCode फोन करेगा: तो हमारी नई कार hashCode() के रूप में दिखेगा।

अंत में, ऑब्जेक्ट्स हैशकोड (ऑब्जेक्ट ओ) एक शून्य जांच करेगा। ऑब्जेक्ट शून्य होने पर यह 0 वापस आ जाएगा। अन्यथा, यह ऑब्जेक्ट हैशकोड() विधि को कॉल करेगा।

+0

डिफ़ॉल्ट 'हैशकोड() 'ने लगभग 20 वर्षों तक मेमोरी पता वापस नहीं किया है। यह वास्तव में नहीं हो सकता है। जीसी वस्तुओं को चारों ओर ले जाता है। तथाकथित स्मृति पता एक उमने योग्य हैंडल की है। – EJP

+0

जावा दस्तावेज़ के आधार पर https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode हैशकोड "आमतौर पर ऑब्जेक्ट के आंतरिक पते को परिवर्तित करके कार्यान्वित किया जाता है एक पूर्णांक, लेकिन जावा ™ प्रोग्रामिंग भाषा द्वारा इस कार्यान्वयन तकनीक की आवश्यकता नहीं है। " – ezzadeen