2016-04-23 12 views
9

मैं निम्नलिखित वर्ग है को लागू करने के बावजूद डुप्लिकेट प्रविष्टियों जोड़ता है:HashSet दोनों hashCode() और बराबरी()

Point x=new Point(11,7); 
    Point y=new Point(11,7); 

    System.out.println("hash-code of x=" + x.hashCode()); 
    System.out.println("hash-code of y=" + y.hashCode()); 
    System.out.println("x.equals(y) = " + x.equals(y)); 
    System.out.println("x==y = " + (x==y)); 

    java.util.HashSet<Point> s=new java.util.HashSet<Point>(); 
    s.add(x); 
    System.out.println("Contains "+y.toString()+" = "+s.contains(y)); 
    s.add(y); 
    System.out.println("Set size: "+s.size()); 
    java.util.Iterator<Point> itr=s.iterator(); 
    while(itr.hasNext()) System.out.println(itr.next().toString()); 

मैं हो रही है:, अब

class Point 
{ 
    double x, y; 

    // .... constructor and other functions here 

    public boolean equals(Point p) 
    { 
     if(p==null) return(false); 
     return(x==p.x && y==p.y); 
    } 

    public int hashCode() 
    { 
     int result=17; 

     long c1=Double.doubleToLongBits(x); 
     long c2=Double.doubleToLongBits(y); 

     int ci1=(int)(c1^(c1 >>> 32)); 
     int ci2=(int)(c2^(c2 >>> 32)); 

     result = 31 * result + ci1; 
     result = 31 * result + ci2; 

     return result; 
    } 
} 

अगर मैं निम्नलिखित कोड लिखने निम्नलिखित उत्पादन:

hash-code of x=79052753 
hash-code of y=79052753 
x.equals(y) = true 
x==y = false 
Contains (11.0,7.0) = false 
Set size: 2 
(11.0,7.0) 
(11.0,7.0) 

कृपया मुझे समझने में मदद क्यों होता है() झूठे रिटर्न (बराबर() और hashCode के बाद भी() एक ही मूल्य वापस करें) और मैं इसे कैसे सुधार सकता हूं (यानी। जावा को डुप्लिकेट तत्व जोड़ने से रोकना)। अग्रिम में धन्यवाद।

+2

वाह! यह बहुत अच्छा होगा यदि सभी प्रश्न इतने स्पष्ट और समझदार हैं, और पुन: उत्पन्न करने के लिए कोड और आउटपुट हैं। बहुत बढ़िया! – Seelenvirtuose

उत्तर

7

आप ऑब्जेक्ट में बराबर विधि को ओवरराइड नहीं कर रहे हैं।

बराबरी विधि के हस्ताक्षर है:

public boolean equals(Object obj) 

और नहीं

public boolean equals(Point obj) 

और == का उपयोग कर डबल मूल्यों की तुलना न करें। आपको इसके बजाय Double.equals का उपयोग करना चाहिए।

+1

सरल प्रकारों का मूल्य == –

+2

@ सेर्गेमीमोरोजोव का उपयोग करके तुलना की जा सकती है - नहीं। फ्लोटिंग पॉइंट तुलना के लिए == का उपयोग करने की अनुशंसा नहीं की जाती है। यह सुरक्षित नहीं है। – Madhusudhan

+0

धन्यवाद, यह मेरी समस्या हल हो गया। जहां तक ​​तुलना की जाती है, दस्तावेज़ीकरण के अनुसार, Double.equals झूठी रिटर्न देता है जब -0.0 और +0.0 की तुलना की जा रही है; तो मुझे लगता है कि मैं Double.equals() से == तक चिपकेगा। – user1637645

6

आपने Object.equals(Object) से विधि हस्ताक्षर बदल दिया है, इसलिए आप सही ढंग से equals ओवरराइड नहीं कर रहे हैं। मेरा सुझाव है कि आप इस श्रेणी के बग को पकड़ने के लिए @Override एनोटेशन का उपयोग करें। आपकी विधि कुछ दिखनी चाहिए,

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

मैंने अपना कोड बदल दिया है और इस बार इसे सही तरीके से ओवरराइड किया है और यह मेरी समस्या हल कर चुका है। बहुत बहुत धन्यवाद। – user1637645

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