2012-11-18 14 views
5

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

वहाँ एक तीसरे पक्ष के इंटरफ़ेस या वर्ग है कि इस तरह के एक सुविधा प्रदान करता है है?

+1

क्या आप इनमें से एक का मतलब है? http://download.oracle.com/javase/6/docs/api/java/util/Collections.html?is-external=true#unmodifiableList(java.util.List)। आप अपनी खुद की सूची (एक रणनीति के रूप में) बना सकते हैं, और जब फ्रीज विधि लागू की जाती है, तो आप एक अपरिवर्तनीय सूची के लिए आंतरिक सूची बदलते हैं। – Augusto

उत्तर

1

CopyOnWriteArrayList का उपयोग करने का प्रयास करें।

CopyOnWriteArrayList ज्यादा ArrayList वर्ग की तरह व्यवहार करती है, सिवाय इसके कि जब सूची, संशोधित है अंतर्निहित सरणी को संशोधित करने के बजाय, एक नई सरणी बनाई गई है और पुराने सरणी खारिज कर दिया है। यह मतलब यह है कि एक फोन करने वाले पुनरावर्तक हो जाता है जब (यानी copyOnWriteArrayListRef.iterator()) है, जो आंतरिक रूप से अंतर्निहित CopyOnWriteArrayList वस्तु की सरणी, जो अपरिवर्तनीय है और इसलिए या तो पर तुल्यकालन की आवश्यकता के बिना ट्रेवर्सल के लिए इस्तेमाल किया जा सकता के लिए एक संदर्भ रखती है सूची copyOnWriteArrayListRef या क्लोन() को प्रतिलिपि से पहले copyOnWriteArrayListRef सूची की आवश्यकता है (यानी समवर्ती संशोधन का कोई जोखिम नहीं है) और भी बेहतर प्रदर्शन प्रदान करता है।

3

गुवा पुस्तकालयों के हिस्से के रूप में ImmutableList कक्षा है। मौजूदा Iterable से ImmutableList बनाने के लिए आप copyOf विधि का उपयोग कर सकते हैं, उदाहरण के लिए। अगर ग्राहक अभी भी मूल परिवर्तनशील सूची के लिए एक संदर्भ है

List<String> immutableList = ImmutableList.copyOf(list);

1

Collections.unmodifiableList का उपयोग करते हुए प्रत्यक्ष पर्याप्त नहीं है।

मैं एक सौंपने सूची कार्यान्वयन है कि मूल परिवर्तनशील सूची (प्रतिनिधि) के लिए एक आंतरिक संदर्भ के लिए होता है और आगे विधि के सभी यह करने के लिए कॉल पैदा करेगा। यह हाथ से ऐसे कोड लिखने के लिए एक पिटा है, लेकिन उदाहरण के लिए ग्रहण स्वचालित रूप से आपके लिए उत्पन्न कर सकता है।

फिर freeze विधि बुला की बात है, मैं मूल सूची Collections.unmodifiableList जो यह सुनिश्चित करता है भविष्य विधि के सभी कॉल करने के लिए FreezingList केवल unmodifable दृश्य के माध्यम से मूल प्रतिनिधि के लिए जाने के साथ रैप होगा।

चीजों को और अधिक सुरक्षित बनाने के लिए, लेकिन कम लचीला बनाने के लिए, आप निम्न कन्स्ट्रक्टर को बदल सकते हैं और मूल सूची को पास करने के बजाय (जो क्लाइंट को मूल म्यूटेबल सूची का संदर्भ छोड़ सकता है) आंतरिक रूप से सूची को तुरंत चालू कर सकता है (उदाहरण के लिए ArrayList)।

public class FreezingList<E> implements List<E> { 

    // the original list you delegate to (the delegate) 
    private List<E> list; 

    private boolean frozen = false; 

    public FreezingList(List<E> list) { 
     this.list = list; 
    } 

    public void freeze() { 
     if (!frozen) { 
      list = Collections.unmodifiableList(list); 
      frozen = true; 
     } 
    } 

    // all the delegating methods follow: 
    public int size() { 
     return list.size(); 
    } 

    public E get(int index) { 
     return list.get(index); 
    } 
    // etc. etc. 
}