अतीत में, मैंने कहा है कि एक संग्रह को सुरक्षित रूप से कॉपी करें कुछ ऐसा करें:
public static void doThing(List<String> strs) {
List<String> newStrs = new ArrayList<>(strs);
या
public static void doThing(NavigableSet<String> strs) {
NavigableSet<String> newStrs = new TreeSet<>(strs);
लेकिन क्या ये "कॉपी" कंस्ट्रक्टर हैं, समान स्थिर निर्माण विधियाँ और धाराएँ, वास्तव में सुरक्षित हैं और नियम कहाँ निर्दिष्ट हैं? सुरक्षित रूप से मेरा मतलब है कि जावा भाषा और एक दुर्भावनापूर्ण फोन करने वाले के खिलाफ लागू किए गए संग्रह की मूल मौलिक अखंडता की गारंटी है, एक उचित द्वारा समर्थित है SecurityManager
और इसमें कोई दोष नहीं हैं।
मैं विधि फेंकने के साथ खुश हूँ ConcurrentModificationException
, NullPointerException
, IllegalArgumentException
, ClassCastException
, आदि, या शायद यह भी फांसी।
मैंने String
एक अपरिवर्तनीय प्रकार के तर्क के उदाहरण के रूप में चुना है। इस प्रश्न के लिए, मुझे म्यूटेबल प्रकारों के संग्रह के लिए गहरी प्रतियों में कोई दिलचस्पी नहीं है, जिनके पास अपने स्वयं के गोच हैं।
(स्पष्ट रूप से, मैं OpenJDK स्रोत कोड पर ध्यान दिया है और के लिए जवाब के कुछ प्रकार है ArrayList
और TreeSet
।)
NavigableSet
और अन्य Comparable
आधारित संग्रह कभी-कभी यह पता लगा सकते हैं कि क्या कोई वर्ग compareTo()
सही तरीके से लागू नहीं करता है और एक अपवाद नहीं फेंकता है। यह थोड़ा अस्पष्ट है कि आप अविश्वसनीय तर्क से क्या मतलब है। आपका मतलब है कि एक ईविलवियर खराब स्ट्रिंग्स का एक संग्रह है और जब आप उन्हें अपने संग्रह में कॉपी करते हैं तो कुछ बुरा होता है? नहीं, संग्रह की रूपरेखा बहुत ठोस है, यह लगभग 1.2 के बाद से है।
HashSet
(और सामान्य रूप से अन्य सभी हैशिंग संग्रह) hashCode
तत्वों के कार्यान्वयन की शुद्धता / अखंडता पर निर्भर करते हैं, TreeSet
और (और आप भी नहीं कर सकते हैं) कस्टम तुलनित्र को स्वीकार किए बिना एक समतुल्य प्रति बनाएँ अगर एक है), उस विशेष प्रकार की अखंडता पर भरोसा करता है जिसे संकलन के बाद कभी भी सत्यापित नहीं किया जाता है, इसलिए एक वर्ग फ़ाइल, जिसके साथ या हैंडक्राफ्ट नहीं किया गया है, उसे उल्टा कर सकता है। PriorityQueue
Comparator
EnumSet
enum
javac
new TreeSet<>(strs)
जहां strs
ए है NavigableSet
। यह बल्क कॉपी नहीं है, क्योंकि परिणामस्वरूप TreeSet
स्रोत के तुलनित्र का उपयोग करेगा, जो कि शब्दार्थ को बनाए रखने के लिए भी आवश्यक है। यदि आप केवल निहित तत्वों को संसाधित करने के साथ ठीक हैं, toArray()
तो जाने का रास्ता है; यहां तक कि पुनरावृत्ति क्रम भी रहेगा। जब आप "एलिमेंट एलीमेंट, एलिमेंट एलिमेंट, यूज़ एलिमेंट" के साथ ठीक होते हैं, तो आपको कॉपी बनाने की भी जरूरत नहीं है। समस्या तब शुरू होती है जब आप सभी तत्वों को सत्यापित करना चाहते हैं, सभी तत्वों का उपयोग करके। फिर, आप एक TreeSet
कस्टम w कस्टम कॉपीर पर भरोसा नहीं कर सकते
checkcast
प्रत्येक तत्व के लिए एकमात्र थोक कॉपी ऑपरेशन का प्रभाव toArray
एक विशिष्ट प्रकार के साथ होता है। हम हमेशा इसे खत्म कर रहे हैं। जेनेरिक संग्रह उनके वास्तविक तत्व प्रकार को भी नहीं जानते हैं, इसलिए उनके प्रतिलिपि निर्माता समान कार्यक्षमता प्रदान नहीं कर सकते हैं। बेशक, आप किसी भी चेक को सही उपयोग करने के लिए सुरक्षित कर सकते हैं, लेकिन फिर, मुझे नहीं पता कि आपके प्रश्न क्या लक्ष्य कर रहे हैं। आपको "सिमेंटिक अखंडता" की आवश्यकता नहीं है, जब आप तत्वों का उपयोग करने से पहले तुरंत जाँच और असफल हो जाते हैं।