Как преобразовать универсальный ArrayList в универсальный массив - PullRequest
0 голосов
/ 07 ноября 2018

Когда я звоню printArray в моем 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(). Я понятия не имею, как преобразовать ArrayList в массив и привести его к универсальному одновременно. Примечание. Я не могу изменить параметры функции 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

В другом классе у меня

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

, который вам нужен для функции. Мой профессор настаивал на том, чтобы мы использовали это вместо импорта Function.

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

Вы можете извлечь информацию о типе из 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");
}
0 голосов
/ 07 ноября 2018

Часть первая, вам нужно 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]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...