Подтвердить что ты не робот

Проблема Varargs с ArrayList в Java

Я не понимаю, почему следующее не работает:

public void doSomething(int... args){
  List<Integer> broken = new ArrayList<Integer>(Arrays.asList(args))
}

Его понимание того, что компилятор преобразует "int... args" в массив, поэтому приведенный выше код должен работать.

Вместо работы я получаю:

не может найти символ symbol: конструктор ArrayList (java.util.List <int[] > ) местоположение: класс java.util.ArrayList <java.lang.Integer >

Это странно. Я не добавляю массив в список массивов, я добавляю каждый элемент из списка в arraylist. Что происходит?

4b9b3361

Ответ 1

Java не может автоблокировать массив, а только отдельные значения. Я бы предложил изменить вашу подпись метода на

public void doSomething(Integer... args)

Тогда автобоксинг будет выполняться при вызове doSomething, а не при попытке (и сбое) при вызове Arrays.asList.

Что происходит, Java теперь автоматически устанавливает каждое отдельное значение, поскольку оно передается вашей функции. То, что вы пытались сделать раньше, было, передав int[] to Arrays.asList(), вы просили эту функцию выполнять автобоксинг.

Но автообъект реализуется компилятором - он видит, что вам нужен объект, но передавал примитив, поэтому он автоматически вставил необходимый код, чтобы превратить его в соответствующий объект. Функция Arrays.asList() уже скомпилирована и ожидает объекты, а компилятор не может превратить int[] в Integer[].

Переместив автобоксинг на вызывающих абонентов вашей функции, вы решили эту проблему.

Ответ 2

Вы можете сделать

public void doSomething(int... args){
    List<Integer> ints = new ArrayList<Integer>(args.length);
    for(int i: args) ints.add(i);
}

или

public void doSomething(Integer... args){
    List<Integer> ints = Arrays.asList(args);
}

Ответ 3

В этом случае автобоксинг (автоматическое преобразование от int до Integer) не работает. Вы должны добавить каждый int вручную в список.

Если вам нужен такой код часто, подумайте об использовании commons lang, у которого org.apache.commons.lang.ArrayUtils.toObject(int[])

Ответ 4

Вы можете решить эту проблему с помощью Guava:

List<Integer> broken = new ArrayList<>(Ints.asList(args))

Или с потоками:

List<Integer> broken = Arrays
    .stream(array)
    .boxed()
    .collect(Collectors.toCollection(ArrayList::new));