2011-01-06 14 views
21

मैं एक hashmap है:जावा HashMap.containsKey() बराबर() फोन नहीं करता है

Map<LotWaferBean, File> hm = new HashMap<LotWaferBean, File>(); 

LotWaferBean lw = new LotWaferBean(); 
... //populate lw 
if (!hm.containsKey((LotWaferBean) lw)) { 
    hm.put(lw, triggerFiles[l]); 
} 

LotWaferBean के लिए कोड:

@Override 
public boolean equals(Object o) { 
     if (!(o instanceof LotWaferBean)) { 
       return false; 
     } 
     if (((LotWaferBean) o).getLotId().equals(lotId) 
        && ((LotWaferBean) o).getWaferNo() == waferNo) { 
       return true; 
     } 
     return false; 
    } 

मेरी आईडीई मैं equals() में breakpoints डाल लेकिन यह में कभी निष्पादित नहीं किया जाता है। क्यूं कर?

उत्तर

38

हैशकोड() में ब्रेकपॉइंट डालने का प्रयास करें।

मानचित्र में hashCode() दो वस्तुओं की एक ही नंबर वापसी है, तो यह निर्धारित करने के अगर वे वास्तव में बराबर कर रहे हैं बुलाया जाएगा बराबर।

+14

अधिक विशेष रूप से, यदि आप 'बराबर' विधि को लागू करते हैं, तो आपको मैन्युअल में लिखे गए 'हैशकोड' को लागू करना चाहिए :) –

+7

मुझे ग्रहण में विज़ार्ड का उपयोग करने का एक आसान तरीका मिल गया है, बस स्रोत चला रहा है | हैशकोड() और बराबर() उत्पन्न करें। –

3

JVM कि वस्तु की hashCode की hashCode बाल्टी की जाँच करता है, यदि एक ही hashCode के साथ और अधिक वस्तुओं रहे हैं, तो केवल, बराबर() विधि निष्पादित किया जाएगा। और, डेवलपर को हैशकोड() और बराबर() विधियों के बीच सही अनुबंध का पालन करना चाहिए।

5

सिर्फ अगर 2 hashCodes बराबर, equals() पाश कुंजी के दौरान बुलाया जाएगा।

3

सिर्फ अगर 2 hashCodes बराबर, बराबर होती है() पाश कुंजी के दौरान बुलाया जाएगा।

इस सही जवाब है ... या लगभग। निश्चित रूप से, यदि 2 हैश कोड टकराते हैं (वही सुनिश्चित करता है कि वे उचित हैशप इंप के नीचे टकराव करने के लिए बाध्य हैं), केवल तभी समानता जांच की जाती है।

1

बीटीडब्ल्यू, आपकी बराबर विधि सबसे अधिक गलत है। यदि LotWaferBean ओवरराइड किया गया है, तो आपकी equals विधि सबक्लास उदाहरण स्वीकार करेगी, लेकिन क्या आपका सबक्लास भी करेगा?

यह बेहतर पढ़ना चाहिए:

@Override 
public boolean equals(Object o) { 
    if (o == null || o.getClass() != getClass()) { // << this is important 
     return false; 
    } 

    final LotWaferBean other = (LotWaferBean)o; 
    return other.getLotId().equals(lotId) 
       && other.getWaferNo() == waferNo); 
} 
0

रूप Abimaran Kugathasan बताया गया है, HashMap कार्यान्वयन का उपयोग करता हैश बाल्टी कुशलता कुंजी को देखने के लिए, और केवल बराबरी का उपयोग करता है() मिलान हैश बाल्टी में चाबियाँ तुलना करने के लिए दी गई कुंजी के खिलाफ। यह ध्यान देने योग्य है कि कुंजी हैश-बाल्टी को सौंपी जाती है जब उन्हें हैश मैप में जोड़ा जाता है। यदि आप उन्हें जोड़ने के बाद हैश मैप में कुंजियों को बदलते हैं, तो वे अपने हैश कोड को बदल देंगे, तो वे उचित हैश-बाल्टी में नहीं होंगे; और मानचित्र तक पहुंचने के लिए मिलान करने वाली कुंजी का उपयोग करने का प्रयास उचित हैश-बाल्टी पाएगा, लेकिन इसमें परिवर्तित कुंजी नहीं होगी।

class aMutableType { 
    private int value; 
    public aMutableType(int originalValue) { 
    this.value = originalValue; 
    } 
    public int getValue() { 
    return this.value; 
    } 
    public void setValue(int newValue) { 
    this.value = newValue; 
    } 
    @Override 
    public boolean equals(Object o) { 
     // ... all the normal tests ... 
     return this.value == ((aMutableType) o).value; 
    } 
    @Override 
    public int hashCode() { 
     return Integer.hashCode(this.value); 
    } 
} 
... 
Map<aMutableType, Integer> aMap = new HashMap<>(); 
aMap.put(new aMutableType(5), 3); // puts key in bucket for hash(5) 
for (aMutableType key : new HashSet<>(aMap.keySet())) 
    key.setValue(key.getValue()+1); // key 5 => 6 
if (aMap.containsKey(new aMutableType(6)) 
    doSomething(); // won't get here, even though 
        // there's a key == 6 in the Map, 
        // because that key is in the hash-bucket for 5 

यह कुछ बहुत अजीब दिखने व्यवहार हो सकता है। आपMap.containsKey (theKey) से पहले एक ब्रेकपॉइंट सेट कर सकते हैं, और देख सकते हैं कि केई का मान मैप में एक कुंजी से मेल खाता है, और फिर भी कुंजी के बराबर() को नहीं कहा जाएगा, और इसमें शामिल है() झूठी वापसी करेगा।

के रूप में यहाँ https://stackoverflow.com/a/21601013 बताया गया है, वास्तव में चाबी के लिए परिवर्तनशील प्रकार के उपयोग के संबंध मानचित्र के लिए एक चेतावनी JavaDoc। गैर-हैश मानचित्र प्रकारों में यह विशेष समस्या नहीं होगी, लेकिन जब कुंजी को जगह में बदल दिया जाता है तो अन्य समस्याएं हो सकती हैं।

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