2011-05-13 16 views
9

मैं उत्सुक हूँ क्या है जब एक अस्थायी वर्ग से वस्तुओं का संग्रह लौटने एक बेहतर अभ्यास माना जाता है:जावा में एक आंतरिक संग्रह लौटने के लिए सबसे अच्छा अभ्यास क्या है?

public class Someclass { 

    public List<String> strings; 

    public add(String in){ strings.add(in); } 
    public remove(String in) { strings.remove(in); } 

    //THIS 
    public List<String> getStrings(){ 
    return Collections.unmodifiableList(strings); 
    } 

    //OR THIS 
    public List<String> getStrings(){ 
    return new ArrayList(strings); 
    } 
} 

मैं हमेशा एक Unmodifiable में आंतरिक संग्रह लपेटकर ग्रहण सबसे अच्छा तरीका था के बाद से मैं नहीं देखा एक प्रतिलिपि बनाने के ऊपरी हिस्से को लेने का एक कारण। हालांकि, यह मेरे लिए हुआ कि आंतरिक रूप से सूची में किए गए किसी भी बदलाव को क्लाइंट के सामने उजागर किया जाएगा जो मुझे खराब मानता है।

उत्तर

5

मुझे नहीं लगता कि इसके लिए एक सरल "सर्वोत्तम अभ्यास" जवाब है। यह वास्तव में इस बात पर निर्भर करता है कि आप कितने मशीन संसाधनों को कक्षा डेटा अबास्ट्रक्शन सीमाओं का उल्लंघन रोकने पर खर्च करने के इच्छुक हैं। और यह इस बात पर निर्भर करता है कि आप वास्तव में किस जोखिम को कम करने की कोशिश कर रहे हैं; जैसे क्या यह सरल (गैर-समवर्ती) कीड़े, समवर्ती बग, या सूचना लीक है।

विकल्प हैं:

  • कुछ न करें; यानी संग्रह को वापस कर दें।
  • एक अपरिवर्तनीय रैपर वर्ग में लिपटे संग्रह को वापस करें।
  • संग्रह की एक उथली प्रतिलिपि वापस करें।
  • संग्रह की एक गहरी प्रतिलिपि लौटें।

प्रतिलिपि की सीधी लागत के अतिरिक्त, अन्य प्रदर्शन से संबंधित कारक स्मृति उपयोग और कचरा उत्पादन और समरूपता पर प्रभाव हैं। उदाहरण के लिए, यदि एकाधिक धागे संग्रह को अद्यतन कर रहे हैं और/या "प्राप्त" कर रहे हैं, तो संग्रह की एक प्रति बनाने में आम तौर पर इसे लॉक करना शामिल होता है ... जो संभावित रूप से ऑपरेशन को एक कॉन्सुरेंसी बाधा उत्पन्न कर सकता है।

संक्षेप में, आपको संभावित या वास्तविक जोखिमों और सावधानी बरतने की लागत के विरुद्ध लागत/प्रदर्शन प्रभाव को संतुलित करने की आवश्यकता है।

1

मुझे उत्तरार्द्ध करना पसंद है, लेकिन .clone() विधि का उपयोग करना।

+0

बाद दृष्टिकोण, नए ArrayList का उपयोग कर, या .clone का उपयोग कर(), सही दृष्टिकोण संगामिति मुद्दों को कम करना है। Collections.unmodifiableList() एक बहु थ्रेडेड वातावरण में संभव संगामिति मुद्दों बढ़ जाती है। –

0

यदि आप परिवर्तनों को उजागर करने के बारे में चिंतित हैं; और आपका ऑब्जेक्ट क्लोनबल लागू करता है, तो आप अपनी ऑब्जेक्ट सूची की क्लोन गहरी प्रति वापस आवेदक को वापस कर सकते हैं।

0

'नए ArrayList (तार)' की तुलना में 'Collections.unmodifiableList (तार)' सुरक्षित है।

क्योंकि Collections.unmodifiableList सिर्फ स्रोत सूची अग्रेषित करता है।

नमूना:

List<String> list1 = someclass.getStrings(); //Use Collections.unmodifiableList(strings) implementation 
List<String> list2 = someclass.getStrings(); //Use new ArrayList(strings) implementation 

someclass.add("foo"); 

अब, आप देखेंगे List1 जोड़ा जाता है! सूची 2 नहीं।

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