[英]How to cast a Generic ArrayList to a Generic Array
When I call printArray
in my pvsm, the error I keep receiving is: 当我打电话printArray
在我pvsm,错误我不断收到的是:
Exception in thread "main" java.lang.ClassCastException:
java.base/[Ljava.lang.Object; cannot be cast to java.base/[Ljava.lang.Integer
I know the problem is with the R[] result = (R[]) list.toArray()
. 我知道问题出在R[] result = (R[]) list.toArray()
。 I have no idea how to convert the ArrayList to an array and cast it to a generic at the same time. 我不知道如何将ArrayList转换为数组并将其同时转换为泛型。 Note I cannot change the parameters of the function map
or add any new functions. 注意:我无法更改功能map
的参数或添加任何新功能。
public class Homework2 {
public static void main(String[] args){
Function<Integer,Integer> function = new CalculateSuccessor();
Double[] d= {2.0,4.0,8.0};
Integer[] i= {2,4,8};
printArray(map(function,i));
}
@SuppressWarnings("unchecked")
public static <R,D> R[] map(Function<R,D> function, D[] array){
ArrayList<R> list = new ArrayList<>();
for (D element: array){
list.add(function.apply(element));
}
// THIS LINE OF DAMN CODE
R[] result = (R[]) list.toArray();
return result;
}
public static <R> void printArray(R[] array){
System.out.print("{ ");
for (R element: array){
System.out.print(element + ", ");
}
System.out.print("}");
}
public static class CalculateSuccessor implements Function<Integer,Integer> {
@Override
public Integer apply(Integer parameter) {
return parameter * 2;
}
} //End CalcSuc
} //End Homework2
In another class I have 在另一堂课上
public interface Function<R,D> {
public R apply(D parameter);
}
which you need for the function.apply. 您需要的function.apply。 My professor insisted we use this instead of importing Function. 我的教授坚持认为我们使用此函数而不是导入Function。
Part one, you need the Class<R>
in order to dynamically create an array R[]
. 第一部分,您需要Class<R>
才能动态创建数组R[]
。 I would prefer Arrays.toString
over implementing my own version of that. 与实现自己的版本相比,我更喜欢Arrays.toString
。 I also needed a Function<D, R>
(not a Function<R, D>
). 我还需要一个Function<D, R>
(不是Function<R, D>
)。 But making those changes like 但是进行这些更改
public static void main(String[] args) {
Function<Integer, Integer> function = new CalculateSuccessor();
Double[] d = { 2.0, 4.0, 8.0 };
Integer[] i = { 2, 4, 8 };
System.out.println(Arrays.toString(map(Integer.class, function, i)));
}
public static <R, D> R[] map(Class<R> cls, Function<D, R> function, D[] array) {
ArrayList<R> list = new ArrayList<>();
for (D element : array) {
list.add(function.apply(element));
}
return list.toArray((R[]) Array.newInstance(cls, list.size()));
}
I get 我懂了
[4, 8, 16]
You can extract the type information from the Function<D,R>
because you implemented it with an actual class. 您可以从Function<D,R>
提取类型信息Function<D,R>
因为您是通过实际的类实现的。 So together with @Elliott Frisch answer. 因此,与@Elliott Frisch一起回答。
public static <R, D> R[] map(Function<D, R> function, D[] array) {
ArrayList<R> list = new ArrayList<>();
for (D element : array) {
list.add(function.apply(element));
}
Class<?> componentClass = extractReturnType(function)
return list.toArray((R[]) Array.newInstance(componentClass, list.size()));
}
private static Class<?> extractReturnType(Function<?, ?> function) {
Type[] interfaces = function.getClass().getGenericInterfaces();
for(Type iface:interfaces) {
if (iface instanceof ParameterizedType && Function.class.equals(((ParameterizedType) iface).getRawType())) {
return (Class<?>) ((ParameterizedType) iface).getActualTypeArguments()[1];
}
}
throw new IllegalArgumentException("Unable to extract type information");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.