2012-02-16 15 views
22

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

यहाँ कुछ कोड है:

import java.util.ArrayList; 
import java.util.List; 

public class Foo { 

    private String id; 


    public static void main(String... args){ 
     Foo a = new Foo("ID1"); 
     Foo b = new Foo("ID2"); 
     Foo c = new Foo("ID3"); 
     List<Foo> fooList = new ArrayList<Foo>(); 
     fooList.add(a); 
     fooList.add(b); 
     fooList.add(c); 
     System.out.println(fooList.contains("ID1")); 
     System.out.println(fooList.contains("ID2")); 
     System.out.println(fooList.contains("ID5")); 
    } 

    public Foo(String id){ 
     this.id = id; 
    } 

    @Override 
    public boolean equals(Object o){ 
     if(o instanceof String){ 
      String toCompare = (String) o; 
      return id.equals(toCompare); 
     } 
     return false; 
    } 



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

उत्पादन: झूठी झूठी झूठी

उत्तर

34

इसका कारण यह है अपने equals()सममित नहीं है:

new Foo("ID1").equals("ID1"); 

लेकिन

"ID1".equals(new Foo("ID1")); 

सत्य नहीं है। इस का उल्लंघन करती है equals() अनुबंध:

के बराबर होती है विधि में गैर-शून्य वस्तु संदर्भों पर एक तुल्यता संबंध लागू करता है:

  • [...]

  • यह सममित है: के लिए कोई गैर-शून्य संदर्भ मान x और y, x.equals(y) सत्य वापस आना चाहिए यदि केवल y.equals(x)true लौटाता है।

यह कर्मकर्त्ता नहीं है या तो:

  • यह कर्मकर्त्ता है: किसी भी गैर-शून्य संदर्भ मूल्य x के लिए, x.equals(x) सच लौटना चाहिए।
Foo foo = new Foo("ID1"); 
foo.equals(foo) //false! 

@mbockusequals() का सही कार्यान्वयन प्रदान करता है:

public boolean equals(Object o){ 
    if(o instanceof Foo){ 
    Foo toCompare = (Foo) o; 
    return this.id.equals(toCompare.id); 
    } 
    return false; 
} 

लेकिन अब आप Foo के उदाहरण से गुजरना होगा:

System.out.println(fooList.contains(new Foo("ID1"))); 
System.out.println(fooList.contains(new Foo("ID2"))); 
System.out.println(fooList.contains(new Foo("ID5"))); 

अंत में आप hashCode() को लागू करना चाहिए संगत परिणाम प्रदान करने के लिए (यदि दो वस्तुओं बराबर हैं, वे बराबर hashCode() होना आवश्यक है):

@Override 
public int hashCode() { 
    return id.hashCode(); 
} 
+0

मैं एक साधारण जोड़ा हैश कोड, अभी भी काम नहीं करता है ... –

+0

@ReidMac: मैं गलत था, यह 'बराबरी के बारे में है()' सममित नहीं किया जा रहा, मेरे संपादन पर एक नजर है। 'HashCode()' इस मामले में कोई संबंध नहीं है, लेकिन फिर भी आप इस सिद्धांत –

+0

अजीब का पालन करना चाहिए कि हम इस 'नई फू (" ID1 ") का उपयोग करने की जरूरत है;' कस्टम उपयोग करने के लिए सम्मेलन विधि के बराबर होती है। इसके पीछे कोई कारण? – Dish

4

आप को लागू करना चाहिए hashCode

@Override 
public int hashCode() { 
    return id.hashCode(); 
} 

भले ही ArrayList के लिए काम करता है शामिल इसके बिना। आपकी बड़ी समस्या यह है कि आपके बराबर स्ट्रिंग की अपेक्षा करते हैं, फू ऑब्जेक्ट्स नहीं और आप स्ट्रिंग्स के साथ पूछते हैं। कार्यान्वयन सूची में प्रत्येक इजेक्ट पूछा कि अगर वे स्ट्रिंग आप भेजने के लिए बराबर थे, तो अपने कोड काम कर सकता था, लेकिन कार्यान्वयन स्ट्रिंग पूछता है कि यह आपके फू objets जो यह निश्चित रूप से नहीं है के बराबर है।

उपयोग

@Override 
public boolean equals(Object o){ 
    if(o instanceof Foo){ 
     String toCompare = ((Foo) o).id; 
     return id.equals(toCompare); 
    } 
    return false; 
} 

के बराबर होती है और उसके बाद की जाँच शामिल है

System.out.println(fooList.contains(new Foo("ID1"))); 
9

आपका बराबरी विधि hashCode() फ़ंक्शन अधिभावी के साथ बदल दिया जाना चाहिए। वर्तमान में आप यह देखने के लिए जांच कर रहे हैं कि आप जिस ऑब्जेक्ट की तुलना कर रहे हैं वह स्ट्रिंग का एक उदाहरण है, जब आपको Foo ऑब्जेक्ट्स की जांच करने की आवश्यकता होती है।

public boolean equals(Object o){ 
    if(o instanceof Foo){ 
     Foo toCompare = (Foo) o; 
     return this.id.equals(toCompare.id); 
    } 
    return false; 
} 

आप ग्रहण का उपयोग कर रहे हैं, मैं ग्रहण hashCode पैदा करते हैं और स्रोत पर जाकर आप के लिए बराबर होती होने की सिफारिश करेंगे -> hashCode() और बराबरी() उत्पन्न ...

+1

+1, मैंने आपके कोड स्निपेट को मेरे उत्तर में कॉपी किया, आशा है कि आपको कोई फर्क नहीं पड़ता। –

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