下面产生一个ClassCastException,我无法确定原因。我知道由于不变与共变的特性,以及泛型数组不可重构的事实,泛型数组有点犯忌,但不明白为什么会产生RuntimeException。
...
Integer[] sap = (Integer[]) iterableToArray(path.pathTo(w));
}
private <T> T[] iterableToArray(Iterable<T> it){
ArrayList<T> list = new ArrayList<>();
for(T o : it)
list.add(o);
return (T[]) list.toArray();
}
你可以这样做。
private static <T> T[] iterableToArray(Iterable<T> it, T[] arrayTemplate){
ArrayList<T> list = new ArrayList<>();
for(T o : it)
list.add(o);
return list.toArray(arrayTemplate);
}
像这样调用
Integer[] sap = iterableToArray(path.pathTo(w), new Integer[0]);
你必须给一个变量传递一个重新定义的类型,用于 T
因为该方法 iterableToArray
需要一个数组来创建。你不需要将 iterableToArray
所以这种用法是类型安全的。
变量 arrayTemplate
仅用于将类型传递给方法。由于结果不适合放在大小为0的数组中,所以方法 toArray
制作一个新的数组。这通常比将一个所需大小的数组传递给方法 toArray
. 而且也比较简单。所以这是首选的方式。
如果iterable是整数的iterable,而且你使用的是java 8+,那么你可以用这个方法来实现
Iterable<Integer> iterable = Arrays.asList(5, 7, 11, 13, 17);
Integer[] numbers = StreamSupport.stream(iterable.spliterator(), false).toArray(Integer[]::new);
你不能投 Object[]
到 Integer[]
.
只要你不能实例化一个通用类型数组(new T[]
),您必须提供 IntFunction<T[]> generator
生成一个新的数组,该数组具有所需类型和提供的长度。参见 爪哇.
static <T> T[] iterableToArray(Iterable<T> it, IntFunction<T[]> toArrayFunction) {
List<T> list = new ArrayList<>();
for (T o : it) {
list.add(o);
}
return list.toArray(toArrayFunction);
}
.应简化为.。
static <T> T[] iterableToArray(Iterable<T> it, IntFunction<T[]> toArrayFunction) {
return StreamSupport.stream(it.spliterator(), false).toArray(toArrayFunction);
}
使用方法引用的用法相当简单。
Integer[] sap = (Integer[]) iterableToArray(path.pathTo(w), Integer[]::new);