Perché il mio codice non funziona?
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] + " "); } } }
Il risultato è: 0 1 2 3 4 5 6 7 8 9.
Mi aspettavo una sequenza casualmente mescasting.
Arrays.asList()
non può essere applicato agli array di tipo primitivo come previsto. Quando applicato a int[]
, Arrays.asList()
produce una lista di int[]
s invece di lista di Integer
s. Pertanto mischia una lista appena creata di int[]
.
Questo è un comportamento sottile di argomenti variadici e generici in Java. Arrays.asList()
è dichiarato come
public static List asList(T... a)
Quindi, può prendere diversi argomenti di qualche tipo T
e produrre una lista contenente questi argomenti, oppure può prendere un argomento di tipo T[]
e restituire una lista supportata da questa matrice (è così che funzionano gli argomenti variadici).
Tuttavia, quest’ultima opzione funziona solo quando T
è un tipo di riferimento (cioè non un tipo primitivo come int
), poiché solo i tipi di riferimento possono essere usati come parametri di tipo in generici (e T
è un parametro di tipo).
Quindi, se si passa int[]
, si ottiene T
= int[]
e il codice non funziona come previsto. Ma se passi la matrice del tipo di riferimento (ad esempio, Integer[]
), ottieni T
= Integer
e tutto funziona:
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] + " "); }
Prova ad aggiungere questa riga di codice al test:
List l=Arrays.asList(arr); System.out.println(l);
Vedrai che stai stampando un singolo List
elementi.
Usando Arrays.asList
su una matrice primitiva, asList
considera l’ int[]
come un singolo object piuttosto che una matrice. Restituisce una List
invece di una List
. Quindi, stai basicamente mischiando un singolo List
elementi e quindi non viene mescolato nulla.
Si noti che alcune delle risposte già fornite sono errate perché asList
restituisce un elenco supportato dall’array originale, non viene copiato nulla: tutte le modifiche si riflettono nell’array originale.
Questo non funziona perché la chiamata a shuffle
funziona sull’elenco restituito da Arrays.asList
, non sull’array sottostante. Pertanto, quando si esegue l’iterazione sull’array per stampare i valori, non è cambiato nulla. Quello che vuoi fare è salvare un riferimento List
restituito da Arrays.asList
, e poi stampare i valori di Arrays.asList
(piuttosto che i valori dell’array) dopo averlo shuffle
.
Memorizza la lista restituita da Arrays.asList e shuffle che …
List myShuffledList = Arrays.asList(arr); Collections.shuffle(myShuffledList);