2011-05-27 9 views
55

निम्नलिखित कोड पर:java.lang.IndexOutOfBoundsException: स्रोत गंतव्य में फिट नहीं करता है

static void findSubsets (ArrayList<Integer> numbers, int amount, int index) 
{ 
    ArrayList <Integer> numbersCopy = new ArrayList<Integer>(numbers.size()); 
    Collections.copy(numbersCopy, numbers); 
} 

मैं त्रुटि हो रही है:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Source does not fit in dest 
     at java.util.Collections.copy(Collections.java:548) 
     at backtracking2.Main.findSubsets(Main.java:61) 

क्यों?

उत्तर

71

क्षमता आकार के बराबर नहीं है। आकार पैरामीटर जिसे आप पास कर रहे हैं बस आकार के लिए पर्याप्त स्मृति आवंटित करता है। यह वास्तव में तत्वों को परिभाषित नहीं करता है। यह वास्तव में Collections.copy की मूर्खतापूर्ण आवश्यकता है, लेकिन फिर भी यह एक है।

Collections.copy JavaDocs से महत्वपूर्ण हिस्सा:

The destination list must be at least as long as the source list. If it is longer, the remaining elements in the destination list are unaffected.

तुम बस ArrayList के निर्माता को List पारित मुद्दा पूरी तरह से बचने के लिए List के सभी कॉपी करने के लिए करना चाहिए।

+2

मैंने प्रतिलिपि बनाई है, क्योंकि इसे कन्स्ट्रक्टर में जोड़ना एक [बी] उथला [/ b] प्रतिलिपि करेगा और एक गहरी प्रति के समान नहीं होगा। मूल सूची में तत्वों को जोड़ना, उन्हें 'प्रतिलिपि' सूची में भी बदल देगा – Boy

+2

@ बॉय आपका बिंदु गलत है। [ArrayList के लिए स्रोत कोड] देखें (http://hg.openjdk.java.net/jdk7/modules/jdk/file/a37326fa7f95/src/share/classes/java/util/ArrayList.java#l150) जहां एक गहरा सूची _ की प्रतिलिपि 'toArray' और ['Arrays.copyOf'] पर कॉल के माध्यम से की जाती है (https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#copyOf (यू [],% 20int,% 20java.lang.Class))। 'NumbersCopy = new ArrayList (संख्याएं) के बाद किसी भी सूची में किए गए परिवर्तन _not_ को दूसरे को प्रभावित नहीं करते हैं। यह निश्चित रूप से कन्स्ट्रक्टर के उद्देश्य को हरा देगा (और यह 'संग्रह' लेता है और वैसे भी 'सूची' नहीं)। – pickypg

+1

@ बॉय जब तक आप इस तथ्य पर नहीं पहुंच रहे हैं कि _elements yourself_ को भी एक वास्तविक गहरी प्रतिलिपि के लिए पुनर्निर्मित नहीं किया गया है? चूंकि जावा को कॉपी कन्स्ट्रक्टर की आवश्यकता नहीं होती है, इसलिए यह लगभग असंभव आवश्यकता होगी और एक ['संग्रह। कॉपी 'या तो प्रदर्शन नहीं करता है] (http://hg.openjdk.java.net/jdk7/modules/jdk/file/ a37326fa7f95/src/शेयर/वर्गों/जावा/util/Collections.java # l545)। – pickypg

14

एक बहुत अच्छा सवाल है कि और यह लगभग निश्चित रूप से तथ्य यह है कि एक संग्रह क्षमता की स्थापना जरूरी अंतर्निहित वस्तुओं का आवंटन नहीं करता है के साथ क्या करना है, लेकिन क्यों आप इसे इस तरह से कर रहे हैं जब आप बस कर सकते हैं:

ArrayList <Integer> numbersCopy = new ArrayList<Integer>(numbers); 
+2

यह प्रतियां संदर्भ – temirbek

3

निर्माता ArrayList(Collection<? extends E> c) नव निर्मित उदाहरण में c से हर तत्व कॉपी जाएगा, इस प्रकार numbersCopy में numbers को कॉपी। यह numbersCopy.addAll(numbers) जैसा ही है, जो वास्तव में आपको चाहिए।

यह समझ में आता है कि Collection.copy को dest सरणी की आवश्यकता है ताकि source सरणी से सभी तत्वों को पकड़ सकें। एक समान समानता सी फंक्शन memcpy और इसी तरह की है।

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