2017-08-01 29 views
5
class Point{ 
    int x, y, l; 

    Point(int x, int y, int l){ 
     this.x =x; 
     this.y =y; 
     this.l=l; 
    } 
    @Override 
    public int hashCode() { 
     return y; 
    } 

    @Override 
    public boolean equals(final Object obj) { 
     if(this == obj) return true; 
     if(!(obj instanceof Point)) return false; 
     Point p = (Point) obj; 
     return this.x == p.x && this.y == p.y; 
    } 
} 

    TreeMap<Point,Integer> sortedMap = new TreeMap<>((p1, p2)-> p1.l-p2.l); 
    sortedMap.put(new Point(4,5,0),0); 
    sortedMap.put(new Point(5,5,0),6); 
    System.out.println(sortedMap.size()); -> Output: 1 
    System.out.println((new Point(4,5,0)).equals(new Point(5,5,0))); -> Output -> False. 

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

मुझे यकीन नहीं है कि मेरा हैशैप आकार क्यों है 1. अगर मुझे हैशप गलत तरीके से काम कर रहा है तो कृपया मुझे बताएं। इस कोड में बग की पहचान करने में मेरी मदद करें?

+2

आपकी समानता जांच 'p1.l - p2.l' क्यों है? –

+0

आप अपने चर 'sortedSet' को क्यों कॉल कर रहे हैं जब यह सेट नहीं है लेकिन नक्शा है? –

+0

@MuratK .: यह एक समानता जांच नहीं है - यह एक आदेश है। –

उत्तर

5

TreeMap केवल आपूर्ति Comparator का उपयोग करता है (या प्राकृतिक आदेश उपलब्ध होने पर) समानता, निर्धारित करने के लिए इतना equals और hashCode कोई फर्क नहीं बनाते हैं।

आपके मामले में, Point दोनों के समान l मान है, इसलिए उन्हें आपके Comparator के अनुसार समान माना जाता है।

आप जब अपनी चाबी के आदेश (और समानता) का निर्धारण करने के लिए अपने Comparator खाते में सभी गुण (l, x और y) लेने के लिए संशोधित कर सकते हैं।

11

आपकी TreeMap मान l भाग (जो कुछ भी होना है) द्वारा तुलना कर रहा है। यही कारण है कि अपने कोड के इस हिस्से करता है:

new TreeMap<>((p1, p2)-> p1.l-p2.l); 

दो अंक आपके द्वारा बनाया गया एक ही l मूल्य (0) होता है अतः वे बराबर माना रहे हैं ... तो put को दूसरी कॉल मौजूदा प्रविष्टि को बदल देता है । TreeMapequals और hashCode का उपयोग नहीं करता है।

ध्यान दें कि आदेश किसी भी क्रमबद्ध मानचित्र की तरह, एक पेड़ नक्शा द्वारा बनाए रखा, और चाहे या नहीं एक स्पष्ट तुलनित्र प्रदान की जाती है, बराबरी के अनुरूप होना चाहिए अगर यह क्रमबद्ध नक्शा करने के लिए है:

से documentation

मानचित्र इंटरफ़ेस को सही ढंग से कार्यान्वित करें। (बराबर के साथ संगत की सटीक परिभाषा के लिए तुलनात्मक या तुलनात्मक देखें।) ऐसा इसलिए है क्योंकि मानचित्र इंटरफ़ेस को बराबर ऑपरेशन के संदर्भ में परिभाषित किया गया है, लेकिन एक क्रमबद्ध नक्शा इसकी तुलना (या तुलना) विधि की तुलना में सभी महत्वपूर्ण तुलना करता है, इसलिए दो कुंजी जो इस विधि के बराबर समझा जाता है, क्रमबद्ध मानचित्र के दृष्टिकोण से बराबर है। सॉर्ट किए गए मानचित्र का व्यवहार अच्छी तरह से परिभाषित किया गया है भले ही उसका ऑर्डरिंग बराबर के साथ असंगत हो; यह सिर्फ मानचित्र इंटरफ़ेस के सामान्य अनुबंध का पालन करने में विफल रहता है।

आपका तुलना जिसके कारण आप परिणाम जो Map अनुबंध का उल्लंघन देख रहे हैं equals के साथ संगत नहीं है। यदि दो अंक equal हैं

+1

* या * 'Comparator.comparingInt (प्वाइंट :: एल)' – Eugene

+0

@ यूजीन वास्तव में, लेकिन यह और अधिक स्क्रीन स्थान लेता है। –

+0

@ KlitosKyriacou है कि * कभी * एक तर्क? यह हर समय मुक्केबाजी/अन-मुक्केबाजी का उपयोग न करके सही काम कर रहा है – Eugene

2
sortedSet.put(new Point(4,5,0),0); 
sortedSet.put(new Point(5,5,0),6); 

इन पुट कॉल का उपयोग आपूर्ति तुलनित्र ((p1, p2)-> p1.l-p2.l) जाँच करने के लिए।

(new Point(4,5,0)).equals(new Point(5,5,0)) 

यह Point कक्षा में ओवरराइड बराबर का उपयोग करता है।

इसलिए अंतर ..

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