如何将通用ArrayList强制转换为通用数组

时间:2018-11-06 21:35:53

标签: java arrays generics arraylist casting

当我在pvsm中调用Exception in thread "main" java.lang.ClassCastException: java.base/[Ljava.lang.Object; cannot be cast to java.base/[Ljava.lang.Integer 时,我一直收到的错误是:

R[] result = (R[]) list.toArray()

我知道问题出在map上。我不知道如何将ArrayList转换为数组并将其同时转换为泛型。注意,我无法更改函数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 的参数或添加任何新函数。

public interface Function<R,D> {
     public R apply(D parameter);
}

我在另一堂课上

$('.info').mCustomScrollbar({
    theme: 'dark',
    scrollInertia: 0,
    autoHideScrollbar: false
});

$(".content .slider").each(function() {
    var cur = $(this);
    cur.slider({
        range: "min",
        value: parseInt(cur.attr("data-cur")),
        min: parseInt(cur.attr("data-min")),
        max: parseInt(cur.attr("data-max")),
        step: parseInt(cur.attr("data-step")),
        slide: function( event, ui ) {
            var post = (parseInt(ui.value) >= parseInt(cur.attr("data-max")) ? '+' : '');
            var $input_object = cur.prev();
            $input_object.val( cur.attr("data-symbol") + numberWithCommas(ui.value) + post );
            $input_object.prev().val(cur.prev().val());
        }
    });
});

您需要的功能。我的教授坚持认为,我们要使用它而不是导入Function。

2 个答案:

答案 0 :(得分:0)

第一部分,您需要Class<R>才能动态创建数组R[]。与实现自己的版本相比,我更喜欢Arrays.toString。我还需要一个Function<D, R>(而不是Function<R, D>)。但是进行类似的更改

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()));
}

我明白了

[4, 8, 16]

答案 1 :(得分:0)

您可以从Function<D,R>中提取类型信息,因为您是通过实际的类实现的。因此,与@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");
}