Почему Collections.shuffle () терпит неудачу для моего массива?

Почему мой код не работает?

package generatingInitialPopulation; import java.util.Arrays; import java.util.Collections; public class TestShuffle { public static void main(String[] args) { int[] arr = new int[10]; for (int i = 0; i < arr.length; i++) { arr[i] = i; } Collections.shuffle(Arrays.asList(arr)); for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } } } 

Результат: 0 1 2 3 4 5 6 7 8 9.

Я ожидал случайного перетасования.

Arrays.asList() не может применяться к массивам примитивного типа, как вы ожидаете. Когда применяется к int[] , Arrays.asList() создает список int[] s вместо списка Integer s. Поэтому вы перемещаете вновь созданный список int[] .

Это тонкое поведение вариативных аргументов и генериков в Java. Arrays.asList() объявляется как

 public static  List asList(T... a) 

Таким образом, он может принимать несколько аргументов некоторого типа T и создавать список, содержащий эти аргументы, или он может принимать один аргумент типа T[] и возвращать список, поддерживаемый этим массивом (так работают вариативные аргументы).

Однако последний вариант работает только тогда, когда T является ссылочным типом (т. Е. Не примитивным типом, таким как int ), потому что только ссылочные типы могут использоваться как параметры типа в generics (а T – параметр типа).

Итак, если вы передаете int[] , вы получите T = int[] , и код не работает должным образом. Но если вы передадите массив ссылочного типа (например, Integer[] ), вы получите T = Integer и все будет работать:

 Integer[] arr = new Integer[10]; for (int i = 0; i < arr.length; i++) { arr[i] = i; } Collections.shuffle(Arrays.asList(arr)); for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } 

Попробуйте добавить эту строку кода в свой тест:

 List l=Arrays.asList(arr); System.out.println(l); 

Вы увидите, что вы печатаете один List элементов.

Использование Arrays.asList в примитивном массиве вызывает asList для обработки int[] как одного объекта, а не массива. Он возвращает List вместо List . Итак, вы в основном перетасовываете один List элементов, и поэтому ничего не перетасовывается.

Обратите внимание, что некоторые из уже полученных ответов неверны, поскольку asList возвращает список, поддерживаемый исходным массивом, ничего не копируется – все изменения отражаются в исходном массиве.

Это не работает, потому что вызов shuffle работает в List возвращаемом Arrays.asList , а не в базовом массиве. Таким образом, когда вы перебираете массив для печати значений, ничего не изменилось. То, что вы хотите сделать, это сохранить ссылку на List возвращаемый Arrays.asList , а затем распечатать значения этого List (а не значения массива) после его shuffle .

Сохраните список, повторно сохраненный в Arrays.asList, и перетасуйте его …

 List myShuffledList = Arrays.asList(arr); Collections.shuffle(myShuffledList); 
Interesting Posts
Давайте будем гением компьютера.