मैं बस सोच रहा था, क्या होगा यदि HashMap की कुंजी परिवर्तनशील है, नीचे परीक्षण कार्यक्रम यह प्रदर्शित करता है और मैं यह समझने में असमर्थ हूं कि दोनों बराबर और hashCode विधियां कब वापस आती हैं सत्य और समान मान, hashmap.containsKey false क्यों लौटाता है।

public class MutableKeyHashMap {

    public static void main(String []a){

            HashMap<Mutable, String> map = new HashMap<Mutable, String>();
            Mutable m1 = new Mutable(5);
            map.put(m1, "m1");
            Mutable m2 = new Mutable(5);
            System.out.println(map.containsKey(m2));    

            m2.setA(6);
            m1.setA(6);
            Mutable m3 = map.keySet().iterator().next();

            System.out.println(map.containsKey(m2)+"    "+m3.hashCode()+"       "+m2.hashCode()+"       "+m3.equals(m2));   

    }
}
class Mutable {

    int a;

    public Mutable(int a) {

        this.a = a;
    }

    @Override
    public boolean equals(Object obj) {

        Mutable m = (Mutable) obj;
        return m.a == this.a ? true : false; 
    }

    @Override
    public int hashCode(){
        return a;
    }

    public void setA(int a) {

        this.a = a;
    }

    public int getA() {
        return a;
    }
} 

यह आउटपुट:

सच झूठ 6 6 सच

10
Abidi 20 जुलाई 2011, 23:28

4 जवाब

सबसे बढ़िया उत्तर

javadoc इसकी व्याख्या करता है

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

मूल रूप से, मानचित्र में परिवर्तनशील वस्तुओं को चाबियों के रूप में उपयोग न करें, आप जल जाएंगे

एक्सट्रपलेट करने के लिए, क्योंकि दस्तावेज़ स्पष्ट नहीं हो सकते हैं, मेरा मानना ​​​​है कि यहां प्रासंगिक बिंदु 'बराबर को प्रभावित करने वाले तरीके से बदला गया है', और आपको लगता है कि बराबर (ऑब्जेक्ट) को हर बार शामिल किया जाता है। दस्तावेज़ यह नहीं कहते हैं, शब्दांकन का तात्पर्य है कि उन्हें गणनाओं को कैश करने की अनुमति दी जा सकती है।

source को देखने से ऐसा लगता है कि आपका हैशकोड एक लौटाता है भिन्न मान (5 था, अब 6) है, यह संभव है कि इसे कार्यान्वयन विवरण के आधार पर किसी भिन्न बकेट में देखा जा रहा हो।

14
ptomli 20 जुलाई 2011, 23:46

आप सोच सकते हैं कि क्या इस तरह, मानचित्र में 16 बाल्टी हैं। जब आप इसे ए == 5 के साथ एक वस्तु देते हैं, तो यह इसे बाल्टी 5 में फेंक देता है। अब आप ए को 6 में बदल सकते हैं, लेकिन यह अभी भी बाल्टी 5 में है। नक्शा नहीं जानता कि आपने ए बदल दिया है, यह चीजों को पुनर्व्यवस्थित नहीं करता है आंतरिक रूप से।

अब आप A == 6 के साथ किसी अन्य वस्तु के साथ आते हैं, और आप मानचित्र से पूछते हैं कि क्या उनमें से एक है। यह जाता है और बकेट 6 में दिखता है और कहता है "नहीं, वहाँ कुछ भी नहीं है।" यह आपके लिए अन्य सभी बाल्टियों की जाँच करने वाला नहीं है।

जाहिर है कि चीजों को बाल्टियों में कैसे डाला जाता है, यह उससे कहीं अधिक जटिल है, लेकिन यह मूल रूप से कैसे काम करता है।

10
Affe 20 जुलाई 2011, 23:38

HashMap आपके ऑब्जेक्ट को हैश कुंजी 5 के स्थान पर रखता है। फिर आप कुंजी को 6 में बदलते हैं और containsKey का उपयोग करके मानचित्र से पूछते हैं कि उसमें वस्तु है या नहीं। नक्शा स्थिति 6 को देखता है और कुछ भी नहीं पाता है, इसलिए यह false का उत्तर देता है।

तो ऐसा मत करो।

6
starblue 20 जुलाई 2011, 23:34

जब आप पहली बार "m1" डालते हैं, तो hashCode() 5 था। इस प्रकार HashMap ने मान को उपयुक्त बकेट में रखने के लिए 5 का उपयोग किया। m2 को बदलने के बाद, hashCode() 6 था, इसलिए जब आपने अपने द्वारा डाले गए मान की तलाश करने की कोशिश की, तो वह जिस बाल्टी में दिख रहा था वह अलग था।

0
tskuzzy 20 जुलाई 2011, 23:38