Тип коллекции Java Параметр для массива - PullRequest
0 голосов
/ 02 декабря 2018

Я хочу создать вспомогательный метод, который получает параметр типа Collection для возврата списка.Вот что у меня сейчас:

public class Helper {
    public static <T> T[] CollectionToArray(Collection<T> collection) {
        return collection.stream().toArray(Object[]::new); // Error
    }

    public static <T> T[] ListToArray(List<T> list) {
        return list.stream().toArray(Object[]::new); // Error
    }
}

public class IamSoNoob {
    public void PleaseHelpMe() {

        List<String> list = new ArrayList<>();
        Set<String> set = new HashSet<>();

        String[] arrayFromList = Helper.CollectionToArray(list); // Error
        String[] arrayFromSet = Helper.CollectionToArray(set); // Error

        String[] array = Helper.ListToArray(list); // Error
    }
}

Мои вопросы:

  1. Возможно ли заполнить CollectionToArray(Collection<T>)?
    • Если да, то как?
    • Кроме того, возможно ли передать List и Set в качестве параметра на первое место?
  2. Можно ли завершить ListToArray(List<T> list)?
    • Если да, то как?

Но вот некоторые ограничения из-за моего личного вкуса.

  1. Не знаюхочу использовать @SuppressWarnings
  2. Я действительно хочу сохранить часть .stream().toArray(Object[]::new) (Java 8 part!)

И у меня есть ощущение, что мне нужно исправить часть Object[]::new используя что-то вроде: <T extends Object> или <? extends T>, но я не могу понять.

Пожалуйста, помогите мне, и, пожалуйста, предоставьте объяснение, меня часто смущает Genericи ?.

1 Ответ

0 голосов
/ 02 декабря 2018

Нет, вы абсолютно не можете этого сделать, если бы было возможно, что библиотечный метод Collection.toArray() дал бы вам тот же тип, что и ваш LHS, но вместо этого, когда вы хотите указать точный тип как ваш LHS, вы должны использовать Collection.toArray(T[])(даже если он идет с ArrayStoreExceptions, т.е. программист должен предоставить правильный тип для массива), причина в том, что в вашем toArray() вы указали Object[] в качестве массива, и позже вы не можете привестиэто к любому другому типу, иначе это приведет к ClassCastException.

Причина всего этого hullabaloo заключается в том, как работают дженерики, т. е. во время компиляции, а во время выполнения Java стирает все параметры типа вих верхние границы типов и, следовательно, потеря информации о типах, которая требуется для создания массивов.

Один из безопасных способов сделать это - добавить другой параметр к вашему вспомогательному методу как

public static <T> T[] CollectionToArray(Collection<T> collection, T[] arr) {

            return collection.stream().toArray(value ->Arrays.copyOf(arr,collection.size()));


        }

и использовать егокак

String[] arrayFromList = Helper.CollectionToArray(list, new String[0]);

но тогда всем лучше использовать Collection#toArray(T[]).

...