我想创建一个获取Collection
类型参数以返回列表的辅助方法。这就是我现在拥有的:
public class Helper {
public static <T> T[] CollectionToArray(Collection<T> collection) {
return collection.stream().toArray(Object[]::new); // Error
}
public static <T> T[] ListToArray(List<T> list) {
return list.stream().toArray(Object[]::new); // Error
}
}
public class IamSoNoob {
public void PleaseHelpMe() {
List<String> list = new ArrayList<>();
Set<String> set = new HashSet<>();
String[] arrayFromList = Helper.CollectionToArray(list); // Error
String[] arrayFromSet = Helper.CollectionToArray(set); // Error
String[] array = Helper.ListToArray(list); // Error
}
}
我的问题是:
CollectionToArray(Collection<T>)
?
List
和Set
作为参数吗?ListToArray(List<T> list)
?
但是由于我的个人品味,这里有些限制。
@SuppressWarnings
.stream().toArray(Object[]::new)
部分(Java 8部分!)我有一种感觉,我需要使用Object[]::new
或<T extends Object>
之类的东西来修复<? extends T>
零件,但我真的不知道。
请帮助我,并提供解释,Generic
和?
经常使我感到困惑。
答案 0 :(得分:2)
不,您绝对不能这样做,如果库方法Collection.toArray()
可以为您提供与LHS相同的类型,但是当您想要与LHS相同的类型时,则必须使用{ {1}}(甚至随Collection.toArray(T[])
一起提供,即由程序员决定是否为数组提供正确的类型),原因是在ArrayStoreExceptions
中指定了{{1} }作为数组,以后就不能将其强制转换为其他任何类型,否则将导致toArray()
。
所有这些麻烦的原因是由于泛型的工作方式,即它是编译时的事情,并且在运行时Java将所有类型参数擦除为其上限类型,因此丢失了创建数组所需的类型信息。
一种安全的方法是在辅助方法中添加另一个参数,例如
Object[]
并将其用作
ClassCastException
但是每个人最好使用
public static <T> T[] CollectionToArray(Collection<T> collection, T[] arr) {
return collection.stream().toArray(value ->Arrays.copyOf(arr,collection.size()));
}
。