Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java generics, list of lists

Tags:

java

generics

This thing has me stumped. I have a class as follows:

public class SpecialList implements List<MyType> {
    // overriden methods
}

Now I have the following method contract to respect in a higher class:

public class MyClass {
    private List<SpecialList> bigList = new ArrayList<SpecialList>();

    public void doStuff(List<MyType> list)
    {
        bigList.add((SpecialList)list); // does not compile - invalid cast
    }
}

I really am not sure what I am doing wrong here. I have a class that implements the List<MyType> interface, yet I can't cast that class to a List<MyType>? That doesn't make any sense to me.

I am lost. What am I supposed to do to make this work? I suppose this has something to do with generics covariance but at this point I don't know what is wrong here. Can someone point in the right direction? Thanks.

like image 986
Thomas Avatar asked May 27 '13 06:05

Thomas


3 Answers

not every List<MyType> (Animal) is MyList (Cow)

you are adding animals to list of cows

like image 161
dantuch Avatar answered Oct 20 '22 16:10

dantuch


I would suggest some parameters :

public class MyClass{
    private List<List<MyType>> bigList = new ArrayList<List<MyType>>();

    public <E extends List<MyType>> void doStuff(E list)
    {
        bigList.add(list);
    }
}

When you retrieve an element from your bigList however you cannot specialize the element as it comes from a generic list. If you absolutely need to cast it, maybe your class architecture is not correct. Or you could abusively do this :

public class MyClass{
    private List<List<MyType>> bigList = new ArrayList<List<MyType>>();

    public <E extends List<MyType>> void doStuff(E list)
    {
        bigList.add(list);
    }

    public <E extends List<MyType>> E getStuff(Class<E> myType,int i)
    {
        List<MyType> obj = bigList.get(i);
        if(myType.isInstance(obj)) return (E) obj;
        throw new SomeErrorHere("invalid type for index");
    }
}
like image 2
TecHunter Avatar answered Oct 20 '22 17:10

TecHunter


You defined List<MyList> (i.e. list of MyList). This means that you can add there instances of MyList only. If you are using addAll() you can add list of MyList. But you are trying to add List<MyType>. MyType is definitely not MyList.

And you obviously cannot cast List to MyList.

like image 1
AlexR Avatar answered Oct 20 '22 17:10

AlexR