Почему 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.
Я ожидал случайную последовательность.
Ответы
Ответ 1
Arrays.asList()
не может применяться к массивам примитивного типа, как вы ожидаете. Когда применяется к int[]
, Arrays.asList()
создает список int[]
вместо списка Integer
s. Поэтому вы перемещаете вновь созданный список int[]
.
Это тонкое поведение вариативных аргументов и дженериков в Java. Arrays.asList()
объявляется как
public static <T> List<T> 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] + " ");
}
Ответ 2
Попробуйте добавить эту строку кода в свой тест:
List l=Arrays.asList(arr);
System.out.println(l);
Вы увидите, что вы печатаете один элемент List
.
Использование Arrays.asList
в примитивном массиве вызывает asList
для обработки int[]
как одного объекта, а не массива. Он возвращает List<int[]>
вместо List<Integer>
. Таким образом, вы в основном перетаскиваете один элемент List
, и поэтому ничего не перетасовывается.
Обратите внимание, что некоторые из уже заданных ответов неверны, потому что asList
возвращает список, поддерживаемый исходным массивом, ничего не копируется - все изменения отражаются в исходном массиве.
Ответ 3
Это не работает, потому что вызов shuffle
работает на List
, возвращаемом Arrays.asList
, а не на базовый массив. Таким образом, когда вы перебираете массив для печати значений, ничего не изменилось. Вы хотите сохранить ссылку на List
, возвращаемую Arrays.asList
, а затем распечатать значения этого List
(а не значения массива) после того, как вы shuffle
его.
Ответ 4
Сохраните список, сохраненный в Arrays.asList, и перетасуйте его...
List myShuffledList = Arrays.asList(arr);
Collections.shuffle(myShuffledList);