2010-10-18 36 views
9

मैंने getElements विधि कहा जो Iterable<Element> देता है।"Iterable <Element> को सूची <Element> पर नहीं डाला जा सकता" - 'सूची' प्रकार 'Iterable`' नहीं है?

मैं ऐसा किया:

List<Element> elements = (List<Element>) getElements(); 

यह उत्पन्न त्रुटि:

java.lang.ClassCastException: com.utesy.Element$3 
cannot be cast to java.util.List 

मैंने सोचा था कि एक ListIterable का एक प्रकार था?

+1

पोस्ट 'getElements() के कोड,' विधि –

+1

'List' इंटरफ़ेस' Iterable' इंटरफ़ेस फैली - तो हाँ, 'List' जैसा कि आप कहते हैं, 'Iterable' प्रकार का है। लेकिन इसका मतलब यह नहीं है कि 'getElements' द्वारा जो कुछ भी 'Iterable' वापस किया जाता है वह भी' सूची 'है। सभी सूचियां Iterables हैं, लेकिन सभी Iterables सूची नहीं हैं। –

उत्तर

24

हाँ से List<Element> वापस जाने के लिए, List<T> फैली Iterable<T> की जरूरत है, लेकिन यह है कि यह है कि आप मतलब यह नहीं है सेIterable<T> से List<T> तक कास्ट किया जा सकता है - केवल तभी जब वास्तव में एक उदाहरण का संदर्भ देता है List<T> का प्रकार। Iterable<T> को List<T> इंटरफ़ेस को लागू किए बिना लागू करना पूरी तरह से संभव है ... उस स्थिति में, आप क्या होने की उम्मीद करेंगे?

इसे सरल शब्दों में रखने के लिए, Iterable<T> को Object और List<T> से String पर बदलें। StringObject फैली हुई है, ताकि आप String को Object से कास्ट करने के लिए कोशिश कर सकते हैं ... लेकिन कलाकारों केवल निष्पादन समय पर सफल होगा यदि संदर्भ वास्तव में एक String को संदर्भित करता है (या अशक्त है)।

0

नहीं सभी Iterable रों List रों हैं, इस प्रकार यह एक List को एक मनमाना Iterable कास्ट करने के लिए सुरक्षित नहीं है।

उदाहरण के लिए किसी भी Set ले लो, एक HashSetIterable है, लेकिन तत्वों कोई आदेश है, इसलिए यह List इंटरफ़ेस को लागू नहीं कर सकते, और इस तरह एक List नहीं है।

+2

'' "लेकिन तत्वों के पास कोई ऑर्डर नहीं है, इसलिए यह 'सूची' नहीं है - यही कारण नहीं है कि 'हैशसेट' 'सूची' नहीं है। एक 'हैशसेट' एक 'सूची' नहीं है क्योंकि यह' सूची 'इंटरफ़ेस को लागू नहीं करता है। '' –

+0

@ मैट बॉल, सच ... थोड़ा सुधार ... बेहतर? :) – aioobe

0

अपवाद संदेश से यह स्पष्ट है कि Iterable<Element>List<Element>

को castable नहीं है अतः आप getElements()

2

सूची संग्रह संग्रहित करती है जो बदले में Iterable फैली हुई है। इसलिए आप एक उप प्रकार के लिए डालने की कोशिश कर रहे हैं जो तब तक काम नहीं करेगा जब तक कि एलीमेंट्स() वास्तव में एक सूची वापस नहीं कर रहा है (जो हस्ताक्षर किसी भी तरह से गारंटी नहीं देता है)।

देखें: http://download.oracle.com/javase/1.5.0/docs/api/java/util/List.html

1

List एक subinterface Iterable अर्थ है कि सूची काफी सब कुछ Iterable है कि शामिल की, हालांकि नहीं दूसरी तरह के आसपास है। तो सूची सूची में सभी विधियों के पास इटेबल में बराबर नहीं होगा।

उस तरह के कास्टिंग से बचने की कोशिश करें।

मैं Java 6 API का शीघ्रता से अवलोकन और ट्यूटोरियल कास्टिंग

17

List<Element>Iterable<Element> का एक प्रकार है कवर लेने के लिए आप की सिफारिश करेंगे, लेकिन इसका मतलब यह नहीं है कि सभी Iterable<Element> वस्तुओं List<Element> वस्तुओं रहे हैं। आप List<Element> को Iterable<Element> के रूप में डाले जा सकते हैं, लेकिन दूसरी तरफ नहीं।

एक सेब फल का एक प्रकार है, लेकिन इसका मतलब यह नहीं है कि सभी फल सेब हैं। आप एक सेब को फल के रूप में डाल सकते हैं, लेकिन दूसरी तरफ नहीं।

+13

+1 के लिए 22 9 के प्रतिनिधि – willcodejavaforfood

0

सूची Iterable इंटरफेस लागू करता है लेकिन इसका मतलब यह नहीं है कि Iterable सूची में वापस डाला जा सकता है। Iterable अधिक सामान्य है और होश या कुछ विदेशी प्रकार हो सकता है जो सूची के साथ कोई संबंध नहीं है। (ऐसा लगता है कि getElements() अपनी कक्षा के भीतर getElements के साथ निहित कुछ अज्ञात आंतरिक वर्ग का एक उदाहरण देता है)।

यदि प्राप्त करें सूचियां शामिल होंगी तो यह एक वैध कलाकार होगा। चूंकि getElements() द्वारा लौटाया गया प्रकार वास्तव में एक सूची नहीं था, यह एक रन-टाइम त्रुटि उत्पन्न करता है।

+0

सूची इटरटेबल लागू करता है, और यह * इसका मतलब यह है कि इसे इसे डाला जा सकता है। ओपी की समस्या दूसरी तरफ जा रही है। इसका कार्यान्वयन बनाम विस्तार के साथ इसका कोई लेना-देना नहीं है। –

+0

क्षमा करें, "इसका मतलब यह नहीं है कि इसे कास्ट किया जा सकता है" अस्पष्ट था, मैंने "इसे" भर दिया है, इसलिए आपके पास गलत तरीके से व्याख्या नहीं की जा सकती है। – AshirusNW

24

आप

List<Element> elements = Lists.newArrayList(getElements()); 
+13

... जहां सूची com.google.common.collect.Lists है। – jarnoan

+0

यह करने का सबसे संक्षिप्त तरीका है। अन्यथा आपको एक लंबे कार्यान्वयन की आवश्यकता होगी :-(- या केवल स्कैला का उपयोग करें;) –

4

क्यों नहीं के साथ एक सूची में Iterable कर सकते हैं:

Iterable<Element> i = ...; //is what you have 
    List<Element> myList = new LinkedList<Element>(); 
    for (Element e:i) { 
     myList.add(e); 
    } 

? कोई Google lib की आवश्यकता नहीं है।

+0

अब तक का सबसे आसान तरीका ... –

0

आप instanceof साथ एक गार्ड देने का प्रयास कर सकते हैं:

if (AnElement instanceof AList){ 
    //cast 
    AList = (AnList)Element 
} 
संबंधित मुद्दे