开发者

Transfering a Set with a Wildcarded Generic to a List in Java

开发者 https://www.devze.com 2022-12-26 19:30 出处:网络
I have a data type that contains a set and a method that expects List<? extends MyClass>.The data type has Set<? extends MyClass>.I need to be able to move the stuff out of the set and int

I have a data type that contains a set and a method that expects List<? extends MyClass>. The data type has Set<? extends MyClass>. I need to be able to move the stuff out of the set and into the List. The order it goes into the list doesn't matter, it just needs to start keeping track of it so that it can be reordered when displayed. Suffice to say that changing the Set into a List in the data type is out of the question here.

This seems pretty easy at first. Create a new method that takes a Set instead of a List, changes it into开发者_开发知识库 a list and then passes it on to the old method that just took a list. The problem comes in changing the set to a list.

public void setData(Set<? extends MyClass> data) {
    List<? extends Myclass> newData = ArrayList< /* What goes here? */ >();
    for(ConcordaEntityBean o : data) {
        newData.add(o);
     }
     setData(newData);
}

Obviously, I can't instantiate an ArrayList with a wildcard, it chokes. I don't know the type at that point. Is there some way to pull the type out of data and pass it to ArrayList? Can I just instantiate it with MyClass? Is there some other way to do this?


You can't instantiate it with MyClass because newData is not necessarily of type List<MyClass>, and Java does not support covariance (ie, S extends T does not imply that ArrayList<S> is a subtype of ArrayList<T>).

What you can do is this:

List<MyClass> newData = new ArrayList<MyClass>();

Now, everything in the Set (which is guaranteed to be a subtype of MyClass) can be put into newData.

Generally speaking, wildcard types enforce boundary constraints. You know that Set<? extends MyClass> is a Set parameterized with some type, and that type is bounded from above by MyClass. So when you are dealing with the elements from that Set, you can do no better than to treat them as MyClass objects.


Does this work:

List<MyClass> newData = new ArrayList<MyClass>(data);
setData(newData);

?

Or even a one-liner:

setData(new ArrayList<MyClass>(data));


I know my grasp of writing generic methods is shaky, but it seems like this would work:

public <T extends MyClass> void setData(Set<T extends MyClass> data) {
    setData(new ArrayList<T>(data));
}
0

精彩评论

暂无评论...
验证码 换一张
取 消