我的数据类型包含一个需要List<? extends MyClass>
的集合和方法。数据类型为Set<? extends MyClass>
。我需要能够将这些东西移出集合并进入List。它进入列表的顺序无关紧要,它只需要开始跟踪它,以便在显示时可以重新排序。可以说,在数据类型中将Set更改为List是不可能的。
起初这看起来很简单。创建一个新方法,该方法接受Set而不是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);
}
显然,我不能用通配符实例化一个ArrayList,它会窒息。那时我不知道那种类型。有没有办法从数据中提取类型并将其传递给ArrayList?我可以用MyClass
实例化它吗?还有其他方法可以做到这一点吗?
答案 0 :(得分:6)
您无法使用MyClass
对其进行实例化,因为newData
不一定是List<MyClass>
类型,并且Java不支持协方差(即S
extends {{1并不意味着T
是ArrayList<S>
)的子类型。
你可以做的是:
ArrayList<T>
现在,List<MyClass> newData = new ArrayList<MyClass>();
中的所有内容(保证为Set
的子类型)都可以放入MyClass
。
一般来说,通配符类型强制实施边界约束。您知道newData
是使用某种类型进行参数化的Set<? extends MyClass>
,该类型由Set
从上方开始限制。因此,当您处理MyClass
中的元素时,您最好不要将它们视为Set
个对象。
答案 1 :(得分:1)
这是否有效:
List<MyClass> newData = new ArrayList<MyClass>(data);
setData(newData);
甚至是单行:
setData(new ArrayList<MyClass>(data));
答案 2 :(得分:0)
我知道我对写作generic methods的把握很不稳定,但看起来这样可行:
public <T extends MyClass> void setData(Set<T extends MyClass> data) {
setData(new ArrayList<T>(data));
}