Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Iterable<Element> cannot be cast to List<Element>" - Isn't `List` a type of `Iterable`?

I called a getElements method which returns Iterable<Element>.

I did this:

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

This generates the error:

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

I thought a List was a type of Iterable?

like image 507
snoopy Avatar asked Oct 18 '10 13:10

snoopy


4 Answers

You can turn Iterable into a List with

List<Element> elements = Lists.newArrayList( getElements() );
like image 125
dev_doctor Avatar answered Nov 19 '22 08:11

dev_doctor


Yes, List<T> extends Iterable<T>, but that doesn't mean that you can cast from any Iterable<T> to List<T> - only when the value actually refers to an instance of a type of List<T>. It's entirely possible to implement Iterable<T> without implementing the rest of the List<T> interface... in that case, what would you expect to happen?

To put it in simpler terms, let's change Iterable<T> to Object and List<T> to String. String extends Object, so you can try to cast from Object to String... but the cast will only succeed at execution time if the reference actually refers to a String (or is null).

like image 41
Jon Skeet Avatar answered Nov 19 '22 08:11

Jon Skeet


List<Element> is a type of Iterable<Element>, but that doesn't mean that all Iterable<Element> objects are List<Element> objects. You can cast a List<Element> as an Iterable<Element>, but not the other way around.

An apple is a type of fruit, but that doesn't mean that all fruits are apples. You can cast an apple as a fruit, but not the other way around.

like image 18
Erick Robertson Avatar answered Nov 19 '22 08:11

Erick Robertson


why not:

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

? needs no google lib.

like image 5
Rei Avatar answered Nov 19 '22 10:11

Rei