Мой вопрос о добавлении массива различных классов-оберток с помощью обобщений Java - PullRequest
1 голос
/ 31 мая 2019
public static void doProcess(){
   Integer [] intArray = {2,5,3,8,9};
   returnArray(intArray);
   //Expected output:  27 (sum of all number)
   String[]  strArray =  {"Jack", "Daniel", "Richel"};
   returnArray(strArray);
   //Expected output:  Jack Daniel Richel
   Character[]  charArray = {'A', 'X', 'E'};
   returnArray(charArray);
   //Expected output:  AXE
}

У меня есть вышеуказанный код и метод ниже, который нужно завершить.

private static <E> *** returnArray(E[] value) {
    for(E ele : value) {
        //code for expected output
    }
    //return Expected output
}

Мне нужно заполнить вышеуказанный метод, а также заполнить тип возврата, который здесь показан как ***. Я не могу использовать отдельный метод или ввести какой-либо новый метод.

Ответы [ 2 ]

2 голосов
/ 31 мая 2019

Просто добавьте к ответу @ Lino, чтобы предложить более общий подход: я предполагаю, что вы хотите суммировать числа (будь то целые числа, числа с плавающей запятой или что-то еще) и объединять все что угодно (строки, символы, даже случайные объекты, такие как Durationили Instant).Просто символы будут сдавлены вместе, в то время как строки (или что-то еще, в этом отношении) будут объединены с пробелом.

Вы можете вернуть Object или что-то немного более узкое, которое подходит для обоих чисел истроки (например, Serializable или Comparable<?>);это вряд ли полезно, но мешает вам возвращать действительно случайные вещи.

В качестве альтернативы, вы можете решить всегда возвращать String и просто возвращать сумму в виде строки (для чисел).

Реальная реализация может выглядеть довольно аккуратно, если вы используете потоки Java8:

// the `E` generic type brings you nothing, as you can't make use of it at compile time,
// so you can simply drop it and go with a mere `Object[]` array, as per @Lino
public static <E> Serializable returnArray(E[] values) {

    // exclude null values if any (note that `E` proves itself useless already):
    final Stream<?> stream = Stream.of(values).filter(Objects::nonNull);

    if (values instanceof Number[]) {
        // you can use mapToDouble and doubleValue, for a more accurate sum
        return stream.map(Number.class::cast).mapToInt(Number::intValue).sum();
    } else {
        // squash characters, but use a space separator for anything else
        final String separator = (values instanceof Character[]) ? "" : " ";
        return stream.map(Object::toString).collect(Collectors.joining(separator));
    }
}
1 голос
/ 31 мая 2019

Вы можете использовать instanceof, например, у вас может быть такая конструкция:

public static <E> Object returnArray(E[] value) {
    if(value instanceof String[]) {
        String[] strings = (String[]) value;
        // concat the strings with spaces
    } else if(value instanceof Integer[]) {
        Integer[] ints = (Integer[]) value;
        // sum the integers
    } else if(value instanceof Character[]) {
        Character[] chars = (Character[]) value;
        // concat the characters
    } else {
        // throw exception or handle more cases
    }
}

Я специально исключил реальный код для различных операций, так как это должно просто указать вам правильное направление (и я не буду выполнять вашу работу за вас).

Единственная сложная вещь - это тип возвращаемого значения. Как это не может быть E. Он работает с String с и Integer с, но будет разрываться с Character с, так как 'ABC' не является действительным char, и поэтому вы не можете его вернуть.

Примечание: использование дженериков и instanceof нарушает всю концепцию дженериков. Вы также можете просто удалить его и использовать такой метод:

public static Object returnArray(Object[] value) {
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...