我正在将List接口实现为一个将数据存储在<T>
类型数组中的类。这会导致将Collection作为参数的方法出现问题,因为collection将其对象存储为Object
。如何将Object
转换为T
?简单的铸造不起作用。
class MyCollection<T> implements List<T>{
T[] tab;
MyCollection() {
this.tab = (T[])new Object[10];
}
public boolean addAll(Collection c){
for(Object o : c){
o = (T)o;
for(int i = 0; i < tab.length; i++){
tab[i] = o;
}
}
}
}
我正在尝试:
public boolean addAll(Collection<? extends T> c)
但它失败了:
public boolean retainAll(Collection<?> c)
因为我无法在此处更改集合类型:/
public boolean retainAll(Collection<?> c){
boolean result = false;
for(T t : c){
}
return result;
}
答案 0 :(得分:1)
这是正确的方法吗?
是的,这是正确的做法。这就是接口定义的内容(除了接口使用E
,但这没关系)。
请注意,您的addAll
应该返回boolean
。此外,您不需要投射已实施的addAll
。改为改变你的循环:
for(T o : c){...}
只要您返回retainAll
,您的boolean
也应该没问题。
编辑:
对于retainAll
实施,不需要迭代传入的Collection<?>
并转换为T
。考虑迭代tab
支持数组并查看传入的Collection<?> c
中是否包含每个实例。如果出于某种原因,您绝对需要将c
中的项目用作T
s,则可以投射。
答案 1 :(得分:1)
您应该像这样定义addAll方法:
public boolean addAll(Collection<? extends T> c) {...}
这就是它在Java API中的定义
答案 2 :(得分:1)
实施T
不需要投放到retainAll(...)
。例如:
public boolean retainAll(Collection<?> c){
boolean result = false;
Iterator<T> it = this.iterator();
while (it.hasNext()) {
T t : it.next();
if (!c.contains(t)) {
it.remove();
result = true;
}
}
return result;
}