2010-10-20 34 views
21

मेरा कोड क्यों काम नहीं करता है?क्यों संग्रह .shuffle() मेरी सरणी के लिए विफल रहता है?

package generatingInitialPopulation; 

import java.util.Arrays; 
import java.util.Collections; 

public class TestShuffle { 
    public static void main(String[] args) { 
     int[] arr = new int[10]; 

     for (int i = 0; i < arr.length; i++) { 
      arr[i] = i; 
     } 

     Collections.shuffle(Arrays.asList(arr)); 

     for (int i = 0; i < arr.length; i++) { 
      System.out.print(arr[i] + " "); 
     } 
    } 
} 

परिणाम है: 0 1 2 3 4 5 6 7 8 9.

मैं एक बेतरतीब ढंग से फेरबदल अनुक्रम उम्मीद कर रहा था।

उत्तर

40

Arrays.asList() आदिम प्रकार की सरणियों के लिए लागू नहीं किया जा सकता, जैसा कि आप उम्मीद करते हैं। int[] पर लागू होने पर, Arrays.asList()Integer एस की सूची के बजाय int[]s की एक सूची उत्पन्न करता है। इसलिए आप int[] की एक नव निर्मित सूची को घुमाते हैं।

यह जावा में विविध तर्क और जेनेरिक का एक सूक्ष्म व्यवहार है। Arrays.asList() घोषित किया जाता है के रूप में

public static <T> List<T> asList(T... a) 

इसलिए, यह कुछ प्रकार T के कई तर्क ले और इन तर्कों से युक्त एक सूची का उत्पादन कर सकते हैं, या इसे प्रकार T[] में से एक तर्क ले और (इस सरणी द्वारा समर्थित एक सूची प्रदान कि तरीका बताया गया है सकते हैं विविध तर्क काम करते हैं)।

हालांकि, दूसरा विकल्प काम करता है T एक संदर्भ प्रकार (अर्थात नहीं एक आदिम प्रकार जैसे int), केवल जब क्योंकि केवल संदर्भ प्रकार जेनरिक में प्रकार पैरामीटर के रूप में इस्तेमाल किया जा सकता है (और T एक प्रकार पैरामीटर है)।

तो, यदि आप int[] पास करते हैं, तो आपको T = int[] मिलता है, और आप कोड अपेक्षा के अनुसार काम नहीं करते हैं। लेकिन अगर आप (उदाहरण के लिए, Integer[]) संदर्भ प्रकार की सरणी गुजरती हैं, आप T = Integer हो और सब कुछ काम करता है:

Integer[] arr = new Integer[10]; 

for (int i = 0; i < arr.length; i++) { 
    arr[i] = i; 
} 

Collections.shuffle(Arrays.asList(arr)); 

for (int i = 0; i < arr.length; i++) { 
    System.out.print(arr[i] + " "); 
} 
+0

वाह !!! लेकिन सभी ने कहा कि सूची के लिए लागू परिवर्तन, सरणी एआर के साथ नहीं। यह क्यों काम करता है? – Dmitry

+3

क्योंकि Arrays.asList() सरणी द्वारा समर्थित एक नई सूची बनाता है। यह सरणी की प्रतिलिपि नहीं करता है जैसा कि अन्य ने कहा है। Arrays.asList() द्वारा लौटाई गई सूची में प्रत्येक परिवर्तन भी इसे समर्थित सरणी को बदलता है। – ILMTitan

+0

अब समझ में आया। लेकिन क्यों यह प्राचीन प्रकार के साथ काम नहीं करता है? – Dmitry

-2

यह काम नहीं करता है क्योंकि shuffle पर कॉल List पर चल रहा है Arrays.asList द्वारा लौटाया गया है, अंतर्निहित सरणी पर नहीं। इस प्रकार, जब आप मूल्यों को मुद्रित करने के लिए सरणी पर फिर से सक्रिय होते हैं, तो कुछ भी नहीं बदला है। आप क्या करना चाहते हैं ListArrays.asList द्वारा लौटाए गए संदर्भ को सहेजना है, और उसके बाद shuffle के बाद List (सरणी के मानों के बजाय) के मान मुद्रित करें।

+0

एपीआई कहता है - "निर्दिष्ट सरणी द्वारा समर्थित एक निश्चित आकार की सूची देता है। (लौटाई गई सूची में परिवर्तन" सरणी में "लिखना") - http://download.oracle.com/javase/6 /docs/api/java/util/Arrays.html#asList(T ...) – Jon

+0

तत्काल उत्तर के लिए धन्यवाद! – Dmitry

+0

गलत, 'Arrays.asList() 'द्वारा बनाई गई सूची में किए गए किसी भी बदलाव को सरणी में ही बनाया गया है - सूची तत्वों को संग्रहीत करने के लिए उस सरणी का उपयोग करती है। समस्या यह है कि 'asList' primitives की एक सूची नहीं बना सकता है, इसलिए यह एक तत्व के साथ एक सूची बनाता है: सरणी स्वयं। यह गैर-प्राइमेटिव (उदा। पूर्णांक) वाले सरणी के लिए काम करेगा। –

-3

स्टोर सूची Arrays.asList द्वारा resturned और शफ़ल कि ...

List myShuffledList = Arrays.asList(arr); 
Collections.shuffle(myShuffledList); 
+0

कच्चे प्रकार के बजाय जेनेरिक प्रकारों का उपयोग करना बेहतर है – duduamar

+0

-1 गलत, अन्य उत्तरों देखें। – sleske

6

कोशिश अपने परीक्षण के लिए कोड की इस पंक्ति को जोड़ने:

List l=Arrays.asList(arr); 
System.out.println(l); 

आप होगा देखें कि आप एक तत्व को प्रिंट कर रहे हैं List

Arrays.asList का उपयोग प्राइमेटिव सरणी पर asListint[] को किसी सरणी के बजाय एक ऑब्जेक्ट के रूप में करने के लिए का उपयोग करना। यह List<Integer> के बजाय List<int[]> देता है। तो, आप मूल रूप से एक तत्व List को शफल कर रहे हैं और इसलिए कुछ भी वास्तव में शफल नहीं हो जाता है।

ध्यान दें कि पहले से दिए गए कुछ उत्तर गलत हैं क्योंकि asList मूल सरणी द्वारा समर्थित एक सूची लौटाता है, कुछ भी कॉपी नहीं किया जाता है - सभी परिवर्तन मूल सरणी में दिखाई देते हैं।

+0

में बदलें, लेकिन यह प्राचीन प्रकार के int (व्यवहार int [] को एक ऑब्जेक्ट के रूप में इस तरह से क्यों काम करता है)? – Dmitry

+0

@ डिमिट्री: ऐरे जावा में 'ऑब्जेक्ट' भी हैं और मुझे लगता है कि 'asList (टी ...)' के तर्कों को सरल 'ऑब्जेक्ट' के रूप में व्याख्या किया गया है, क्योंकि 'aslist' primitives की अपेक्षा नहीं करता है। – MAK

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