2012-01-10 14 views
5

इसका जवाब इसलिए इस मुद्दे को मैं आ रही है बताते हैं: HashSet.remove() and Iterator.remove() not workingवर्कअराउंड जब आंतरिक वस्तु में परिवर्तन

मूल रूप से, एक बार मैं HashSet के लिए कुछ जोड़ने के लिए, मैं अपने क्षेत्रों में से किसी को संशोधित करते हैं, तो सेट किसी भी समकक्ष परीक्षण को असफल कर देगा जिसमें एक ऑब्जेक्ट वाले सटीक फ़ील्ड वाले ऑब्जेक्ट होते हैं, क्योंकि हैश कोड को संग्रहीत किया गया था जब यह अलग-अलग फ़ील्ड सेट था।

तो, चूंकि यह जवाब बताता है कि क्या हो रहा है, इस सेट में ऑब्जेक्ट्स के आंतरिक क्षेत्रों को संशोधित करने में सक्षम होने के लिए एक अच्छा कामकाज क्या होगा? या यह सिर्फ संभव नहीं है?

उत्तर

5

उस ऑब्जेक्ट को निकालें जिसे आप सेट से संशोधित करना चाहते हैं, इसे बदलें, और फिर इसे वापस जोड़ें। जहां तक ​​मुझे पता है कि कोई मानक Set कार्यान्वयन नहीं है जो फ़ील्ड से निपट सकता है (जिसका उपयोग hashCode() या compareTo() कार्यान्वयन में किया जाता है) इसे संग्रहीत करते समय बदला जा रहा है।

वैकल्पिक रूप से, पहचान, समानता या स्थान का निर्धारण करने में उपयोग नहीं अगर क्षेत्रों हों (जैसे कि hashCode(), compareTo या equals() में उपयोग नहीं किया) तो कोई समस्या नहीं है।

+0

वोटों की संख्या के बावजूद अपने जवाब का चयन, क्योंकि यह aix के रूप में अनिवार्य रूप से एक ही है और यह आया कुछ सेकंड पहले :) धन्यवाद। मुझे लगता है कि मैं इस उदाहरण में एक सेट का उपयोग कर पुनर्मूल्यांकन कर सकता हूं। – AHungerArtist

7

यदि आपके द्वारा संशोधित फ़ील्ड समानता परीक्षण का हिस्सा नहीं हैं, तो उन्हें हैश कोड गणना का हिस्सा नहीं होना चाहिए। उस स्थिति में कोई समस्या नहीं है: आप बस उन क्षेत्रों को संशोधित कर सकते हैं।

यदि फ़ील्ड समानता परीक्षण का हिस्सा हैं, तो संभवतः सेट से ऑब्जेक्ट को निकालने का सबसे साफ तरीका है, फिर इसे संशोधित करें और फिर से डालें।

यदि यह बाद वाला है, और आप इसे स्वयं कर रहे हैं, तो आप समस्या के लिए डेटा संरचना की पसंद को फिर से देखना चाहेंगे।

3

इसके आसपास काम करने का एकमात्र तरीका hashCode() विधि नहीं है जो किसी भी उत्परिवर्तनीय फ़ील्ड पर निर्भर करता है। यदि वस्तुओं की पहचान और अस्तित्व है जो अपने क्षेत्रों के मूल्यों से स्वतंत्र है, तो यह आसान है - System.identityHashCode() का उपयोग करें। अन्यथा, आप एक एकल गैर-परिवर्तनीय फ़ील्ड पर hashCode() का आधार बना सकते हैं। यदि कोई नहीं है, तो मुझे डर है कि आप भाग्य से बाहर हैं।

1

हैशसेट के बजाय हैश मैप का उपयोग करें। कुंजी को उस अद्वितीय के रूप में परिभाषित करें जो उस समय में नहीं बदलेगा।

-1

किसी अन्य संग्रह (शायद एक LinkedList) का उपयोग करें, और, केवल जोड़ने के पल में विशिष्टता के लिए जाँच की तरह में

public class MySetList<E> extends LinkedList<E> implements Set<E> { 
    private static final long serialVersionUID = 1L; 

    @Override 
    public boolean add(E e) { 
     return new HashSet<E>(this).add(e) ? super.add(e) : false; 
    } 
} 
संबंधित मुद्दे