2010-10-18 4 views
9

Ich rief eine getElements Methode, die Iterable<Element> zurückgibt."Iterable <Element> kann nicht in die Liste <Element> umgewandelt werden" - Ist `List` nicht ein Typ von` Iterable`?

Ich tat dies:

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

Dies erzeugt der Fehler:

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

Ich dachte, ein List eine Art von Iterable war?

+1

schreiben den Code von 'GetElements();' Methode –

+1

Der 'list' Schnittstelle, um den' Iterable' Schnittstelle erweitert - also ja, 'list' ist vom Typ 'Iterable', wie du sagst. Das heißt aber nicht, dass "Iterable" von "getElements" zurückgegeben wird. Alle Listen sind Iterables, aber nicht alle Iterables sind Listen. –

Antwort

24

Ja zurückzukehren, List<T>Iterable<T> erstreckt, aber das bedeutet nicht, dass Sie kann von beliebigIterable<T> bis List<T> - nur wenn der Wert tatsächlich bezieht sich auf eine Instanz von a Art von List<T>. Es ist durchaus möglich, Iterable<T> zu implementieren, ohne den Rest der List<T> Schnittstelle zu implementieren ... in diesem Fall, was würden Sie erwarten?

Um es einfacher zu sagen, lassen Sie uns Iterable<T> zu Object und List<T> zu String ändern. String erstreckt Object, so dass Sie versuchen können Object-String zu werfen ... aber die Besetzung wird erst zur Ausführungszeit erfolgreich sein, wenn die Referenz tatsächlich auf eine String bezieht (oder ist null).

0

Nicht alle Iterable s sind List s, so ist es nicht sicher, eine beliebige Iterable zu einem List zu werfen.

Nehmen Sie eine beliebige Set zum Beispiel, ein HashSet ist Iterable aber die Elemente hat keinen Auftrag, so kann sie die List Schnittstelle nicht implementieren und ist somit kein List.

+2

'' "aber die Elemente haben keine Reihenfolge, also ist es keine' List' "- das ist nicht der Grund, dass ein' HashSet' keine 'List' ist. Ein 'HashSet' ist keine' List', weil es die 'List'-Schnittstelle nicht implementiert. '' –

+0

@Matt Ball, wahr ... ein bisschen umformuliert ... besser? :) – aioobe

0

Von Ausnahmemeldung ist klar, dass Iterable<Element>zu nicht gießbar ist List<Element>

SO müssen Sie List<Element> von getElements()

1

List ist ein Subschnittstelle von Iterable Bedeutung, die Liste so ziemlich alles enthält, die Iterable hat, aber nicht umgekehrt. Daher hätten nicht alle Methoden in einer List-Instanz ein Äquivalent in Iterable.

Versuchen Sie, diese Art von Gießen zu vermeiden.Gießen

Ich würde Ihnen empfehlen Abdeckung einen kurzen Blick auf die Java 6 API und die Tutorials zu nehmen

17

List<Element> eine Art von Iterable<Element> ist, aber das bedeutet nicht, dass alle Iterable<Element> Objekte sind List<Element> Objekte. Sie können eine List<Element> als Iterable<Element>, aber nicht umgekehrt.

Ein Apfel ist eine Art von Obst, aber das bedeutet nicht, dass alle Früchte Äpfel sind. Sie können einen Apfel als Frucht gießen, aber nicht umgekehrt.

+13

+1 für nicht 229k rep – willcodejavaforfood

0

List implementiert die Iterable-Schnittstelle, dies bedeutet jedoch nicht, dass Iterable in List zurückübertragen werden kann. Iterable ist viel allgemeiner und kann Hash oder ein exotischer Typ sein, der keine Beziehung zu List hat. (Es sieht so aus, als ob getElements() eine Instanz einer anonymen inneren Klasse zurückgibt, die neben getElements innerhalb seiner Klasse enthalten ist).

Wenn getElements zufällig Listen enthalten würde, wäre dies eine gültige Umwandlung. Da der von getElements() zurückgegebene Typ nicht wirklich eine List ist, führt dies zu einem Laufzeitfehler.

+0

Liste implementiert Iterable, und dies * bedeutet *, dass es zu ihm umgewandelt werden kann. Das Problem, das das OP hat, geht in die andere Richtung. Das hat nichts damit zu tun. –

+0

Entschuldigung, das "heißt nicht, dass es gegossen werden kann" war unklar, ich habe das "es" ausgefüllt, damit es nicht falsch interpretiert werden kann wie du es hast. – AshirusNW

24

Sie können Iterable sich in eine Liste mit

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

... wo Listen com.google.common.collect.Lists ist. – jarnoan

+0

Dies ist der prägnanteste Weg, dies zu tun. Ansonsten brauchst du eine lange Implementierung :-(- oder benutze einfach Scala;) –

4

warum nicht:

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

? benötigt keine Google Lib.

+0

einfachste Weg so weit ... –

0

Sie können versuchen, eine Wache mit instanceof zu platzieren:

if (AnElement instanceof AList){ 
    //cast 
    AList = (AnList)Element 
} 
Verwandte Themen