2011-08-08 14 views
5

मैं ऐसा कुछ करने का प्रयास कर रहा हूं जो अपेक्षाकृत सरल लगता है: सेट की सूची के आकारों को आकार दें।जावा एक ArrayList <TreeSet <Integer>> सूची <Set<Object>> में कनवर्ट क्यों नहीं कर सकता है?

actual argument java.util.ArrayList<java.util.TreeSet<java.lang.Integer>> cannot be converted to java.util.List<java.util.Set<java.lang.Object>> by method invocation conversion 
कोड की निम्न दो टुकड़े के लिए

:

ArrayList<TreeSet<Integer>> testList = new ArrayList<TreeSet<Integer>>(); 
    TreeSet<Integer>   testSet; 
    int       size = 0; 

    testSet = new TreeSet<Integer>(); 
    testSet.add(new Integer(++size)); 
    testSet.add(new Integer(++size)); 
    testList.add(testSet); 
    testSet = new TreeSet<Integer>(); 
    testSet.add(new Integer(++size)); 
    testList.add(testSet); 

    int expResult = size; 
    int result = Helpers.sizeOfListOfSets(testList); 

अंतिम पंक्ति देता है:

/** 
* Sums the sizes of all sets in a list. Note that while there will be 
* no duplicate elements in a single set, "sister" sets may contain 
* elements, so the value returned is **not** equal to the number of unique 
* elements in all sets. 
* @param list, a List of Sets 
* @return the number of elements contained in all sets 
*/ 
public static int sizeOfListOfSets(List<Set<Object>> list) { 
    int size = 0; 

    for (Set<Object> set : list) { 
     size += set.size(); 
    } 

    return size; 
} 

और फिर पालन करते हुए उसे बुला NetBeans निम्न चेतावनी/त्रुटि देता है संकलन त्रुटि:

error: method sizeOfListOfSets in class Helpers cannot be applied to given types; 
1 error 

तो, java.lang.Integer क्यों java.lang.Object में परिवर्तित नहीं किया जा सकता है?

+1

उचित प्रश्न का शीर्षक है, "क्यों जावा एक' सूची > 'में एक' ArrayList > 'परिवर्तित नहीं कर सकते?" –

उत्तर

14

List<Integer>List<Object> नहीं है। यदि Java ने अनुमति दी है, तो आप List<String> के साथ विधि को कॉल कर सकते हैं और आप टूटा जाएगा। Jeremy Heiler ने बताया कि आप List<? extends Object> का उपयोग कर सकते हैं और आप ठीक होंगे। इसका मतलब है कि Object तक फैले प्रत्येक प्रकार की अनुमति है। सामान्य शब्दकोष में ? को wildcard कहा जाता है।

+1

हालांकि, ए 'सूची ' एक 'सूची <है? वस्तु> 'बढ़ाता है। – Jeremy

+0

@ जेरेमी हेइलर - हाँ। –

+0

'सेट <का उपयोग कर? ऑब्जेक्ट बढ़ाता है> 'वास्तविक तर्क java.util.ArrayList > को java.util में परिवर्तित नहीं किया जा सकता है। सूची > ' – MrDrews

2

कुछ भी आप एक सामान्य प्रकार के रूप में घोषित ठीक उसी सामान्य प्रकार हमेशा होना चाहिए।

List<MyObject> myList = new ArrayList<MyObject>; 

इसका कारण यह है, उदाहरण के लिए यदि आप एक पैरामीटर List<Object> के रूप में घोषणा की थी कि अगर है, और आप इसे एक List<Integer> गुजारें सकता है, तो आप किसी भी तरह जोड़ने में सक्षम हो जाएगा: केवल लगता है कि भिन्न हो सकते हैं आधार प्रकार यानी है उस सूची में ऑब्जेक्ट का, जो प्रकार की सुरक्षा को तोड़ देगा।

हालांकि वाइल्डकार्ड ? का उपयोग करके कोई कामकाज है, फिर भी आप तत्वों को तब तक नहीं जोड़ पाएंगे जब तक कि आप इसे <? super MyObject> पसंद न करें, क्योंकि विरासत पेड़ पर कुछ भी उच्च सूची में जोड़ना ठीक होगा।

2

समस्या एक इंटीजर से ऑब्जेक्ट में परिवर्तित नहीं हो रही है, लेकिन ऑब्जेक्ट की सूची से ऑब्जेक्ट की एक सूची में विफल रहता है क्योंकि List<Integer>List<Object> नहीं है। जावा कंपाइलर जेनेरिक प्रकारों को स्वचालित रूप से डालने का प्रयास नहीं करता है। क्योंकि उस सूची में किसी भी वस्तु डाल करने के लिए आप सक्षम होगा

public static int sizeOfListOfSets(List<Set<? extends Object>> list) 
+0

अधिक जानकारी के लिए कृपया [यह] (http://download.oracle.com/javase/tutorial/java/generics/subtyping.html) देखें। – n0rm1e

+0

अभी भी एक त्रुटि हुई है, हालांकि 'सार्वजनिक स्थैतिक int sizeOfListOfSets (सूची > सूची सेट करें)' नहीं। उत्तर के लिए धन्यवाद। – MrDrews

+0

@ houman001 - यह 'सूची <होना चाहिए? सेट <विस्तारित करता है? ऑब्जेक्ट बढ़ाता है >> ':) –

0

:

आप त्रुटि के साथ दूर होने की कुछ इस तरह करने के लिए अपने विधि घोषणा बदल सकता है। जब आप बाद में अपने मूल सूची संदर्भ से तत्वों तक पहुंचते हैं, तो इसमें गैर-इंटीजर ऑब्जेक्ट्स होंगे, हालांकि सूची को अभी भी List<Integer> के रूप में घोषित किया गया है - जिसका अर्थ यह है कि आप इस बात पर भरोसा नहीं कर सकते कि अब और क्या कहता है। उदाहरण:

List<Integer> intList = new ArrayList<Integer>(); 
doSomething(intList); 
for (Integer i : intList) { 
    // i must be an Integer, so doSomething must not 
    // be able to put non-Integers into that list. 
} 
संबंधित मुद्दे