2013-02-27 213 views
28

अगर मैं लिखनाCollections.unmodifiableList और बचाव की मुद्रा में प्रति

List<Integer> a1 = Arrays.asList(1, 2, 3); 
List<Integer> a2 = Collections.unmodifiableList(a1); 

a2-केवल पढ़ने के लिए लेकिन अगर मैं

a1.set(0,10); 

तो लिखने a2 भी संशोधित किया गया है।

तो एपीआई में कहा गया है:

निर्दिष्ट संग्रह के unmodifiable दृश्य देता है। यह विधि मॉड्यूल को उपयोगकर्ताओं को "केवल पढ़ने के लिए" आंतरिक संग्रहों तक पहुंच प्रदान करने की अनुमति देती है।

फिर, यदि मैं मूल संग्रह को संशोधित करता हूं तो लक्ष्य-प्रतिलिपि संग्रह भी संशोधित किया जाता है?

शायद मैंने अर्थ को गलत समझा और यदि ऐसा है तो का तरीका क्या है उस संग्रह की रक्षात्मक प्रति लिखें?

+1

यदि आप ए 1 का एक अपरिवर्तनीय संस्करण रखना चाहते हैं तो आप ए 1 क्लोन कर सकते हैं और इसे एक अपरिवर्तनीय सूची बना सकते हैं। फिर ए 1 के अपडेट ए 2 को प्रभावित नहीं करेंगे। –

उत्तर

36

हां, आप इसे सही ढंग से समझ गए। विचार यह है कि umodifiableCollection द्वारा लौटाई गई वस्तु को सीधे बदला नहीं जा सकता है, लेकिन अन्य माध्यमों के माध्यम से बदल सकता है (प्रभावी रूप से आंतरिक संग्रह को सीधे बदलकर)।

जब तक किसी आंतरिक सूची में कुछ पहुंच हो, तब तक "अप्रचलित" संग्रह बदला जा सकता है।एक

Collection<Integer> myUmodifiableCollection = Collection.umodifiableCollection(Arrays.asList(1, 2, 3)); 

कुछ भी नहीं के बाद से कभी ListasList द्वारा बनाई गई के लिए एक संदर्भ हो जाता है, यह है:

तुम क्यों आमतौर पर एक unmodifiable संग्रह का निर्माण और यह सुनिश्चित करें कि कुछ भी नहीं कभी आंतरिक सूची प्राप्त कर सकते हैं है कि वास्तव में अपरिवर्तनीय संग्रह।

इस दृष्टिकोण का लाभ यह है कि आपको मूल संग्रह/सूची की प्रतिलिपि बनाने की आवश्यकता नहीं है, जो स्मृति और कंप्यूटिंग शक्ति का उपयोग करने से बचाता है।

GuavaImmutableCollection वर्ग (और इसके उप-वर्ग जैसे ImmutableList) प्रदान करता है जो वास्तविक अपरिवर्तनीय संग्रह (आमतौर पर स्रोत की प्रतिलिपि बनाकर) प्रदान करता है।

+0

'Arrays.asList() 'पहले से ही एक निश्चित आकार सूची देता है। तो हमें 'collects.unmodifiableList()' का उपयोग करके इसे अतिरिक्त रूप से सजाने की आवश्यकता क्यों है? मैं आपको देखता हूं और @ वासिलियास ने एक ही मुहावरे का उपयोग किया है। क्या आप समझा सकते हैं? – Geek

+6

@ गीक: जबकि 'Arras.asList()' एक निश्चित आकार सूची देता है, यह एक अपरिवर्तनीय वापस नहीं करता है। आप अभी भी 'सेट (int, टी)' का उपयोग करके तत्वों को बदल सकते हैं। 'संग्रह .unmodifiableList()' "फिक्स" कि इसे अस्वीकार कर। लेकिन किसी भी वास्तविक दुनिया कोड में मैं शायद गुवा 'इमटेबल लिस्ट' (ऊपर से जुड़ा हुआ) का उपयोग करता हूं, क्योंकि यह लिखने के लिए छोटा है, बहुत स्पष्ट है और हमेशा यह सुनिश्चित कर लें कि कुछ भी "रिसाव" नहीं कर सकता है। –

1

विचार यह है कि आप a2 के माध्यम से सूची को संशोधित नहीं कर सकते हैं।

a1 सूची संशोधित करने से आप वास्तव में a2 में जो भी देखते हैं उसे संशोधित करेंगे - इसका उद्देश्य है।

बस सूची a1 तक पहुँचने के लिए एक सार्वजनिक रास्ता है न, और आप आप क्या चाहते हैं :)

1

एपीआई का कहना है होना चाहिए यह आंतरिक संग्रह अपने मामले में संग्रह नहीं आंतरिक

है मुद्दा यह है कि जब आपके पास कक्षा में एक निजी सूची है, तो उस सूची के लिए एक गेटेट है, तो आप चाहते हैं कि गेटर के कॉलर्स चुड़ैल मामले में सूची को संशोधित करने में सक्षम न हों, आपको एक उमोडिफायबल सूची वापस करनी होगी। अन्यथा लौटाई गई सूची केवल आपकी आंतरिक/निजी सूची का संदर्भ है और इस प्रकार इसकी सामग्री को संशोधित किया जा सकता है।

7

शायद मैंने अर्थ को गलत समझा और यदि ऐसा है तो उस संग्रह की रक्षात्मक प्रति लिखने का तरीका क्या है?

आमतौर पर, आप इसे उस तरह से प्रयोग करेंगे:

private List<Integer> a1 = Arrays.asList(1, 2, 3); 

public List<Integer> getUnmodifiable() { 
    return Collections.unmodifiableList(a1); 
} 

कोई है जो getUnmodifiableऔर कॉल अपने वर्ग की आंतरिक करने के लिए पहुँच नहीं है (यानी वे निजी चर acces नहीं कर सकते a1), लौटाई गई सूची को संशोधित करने में सक्षम नहीं होंगे।

+1

'Arrays.asList()' पहले से ही एक निश्चित आकार सूची देता है। तो हमें 'collects.unmodifiableList()' का उपयोग करके इसे अतिरिक्त रूप से सजाने की आवश्यकता क्यों है? मैं क्या खो रहा हूँ? – Geek

+3

आप ए 1 में नहीं जोड़ सकते हैं लेकिन आप किसी भी आइटम को कुछ अलग सेट कर सकते हैं। – assylias

+0

@assylias वास्तव में आप सूची में ऑब्जेक्ट्स के आंतरिक को संशोधित कर सकते हैं, लेकिन आप पुराने ऑब्जेक्ट को किसी अन्य सूची में बदलने के लिए सेट() विधि का उपयोग नहीं कर सकते हैं। – Sam003

0

a1 और a2 उसी डेटा (मेमोरी) का संदर्भ लेंगे।

गैर-लाभकारी हिस्सा आता है, केवल a2 के साथ प्रवेश के रूप में।

इमेजिंग यदि आप a2 को उस विधि में पास कर रहे हैं जहां आप विधि को बेवकूफ होने की उम्मीद करते हैं। ऐसे मामले a2 मदद करता है।

सारांश में आप a2 सूचक का उपयोग कर डेटा संशोधित नहीं कर सकते।

1

बयान:

Collections.unmodifiableList(a1); 

मूल संग्रह जिसका संशोधक तरीकों UnsupportedOperationException फेंक पर एक आवरण देता है।

रैपर रीड-थ्रू है, जिसका अर्थ है कि यदि आप a1 संशोधित करते हैं, तो परिवर्तन लिपटे संग्रह a2 पर प्रतिबिंबित होते हैं। इसकी गणना से

Collections.unmodifiableList(Collections.list(Collections.enumeration(sourceList))) 

Collections.list() प्रतियां मान:

+1

असल में आप सूची में ऑब्जेक्ट्स के आंतरिक को संशोधित कर सकते हैं, लेकिन आप पुराने ऑब्जेक्ट को किसी अन्य के साथ बदलने के लिए सेट() विधि का उपयोग नहीं कर सकते हैं। – Sam003

0

आप unmodifiable और अपरिवर्तनीय सूची की जरूरत है या अन्य पुस्तकालयों के लिए किसी भी निर्भरता के बिना स्रोत सूची के दूसरे शब्दों unmodifiable नकल में इस प्रयास करें।