Warum Collections.shuffle () für meine Array scheitern?
-
09-10-2019 - |
Frage
Warum kommt der Code nicht funktioniert?
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] + " ");
}
}
}
Das Ergebnis ist:. 0 1 2 3 4 5 6 7 8 9
Ich erwarte ein zufällig gemischt Sequenz .
Lösung
Arrays.asList()
kann nicht auf Arrays von primitivem Typ angewandt werden, wie Sie es erwarten. Wenn auf int[]
angewendet, produziert Arrays.asList()
eine Liste von int[]
s statt Liste der Integer
s. Daher mischen Sie eine neu erstellte Liste der int[]
.
Dies ist eine subtile Verhalten von variadische Argumenten und Generika in Java. Arrays.asList()
wird erklärt, wie
public static <T> List<T> asList(T... a)
So kann es mehrere Argumente von irgendeiner Art T
nehmen und eine Liste erzeugt diese Argumente enthält, oder es kann ein Argument vom Typ T[]
nehmen und eine Liste, die von diesem Array unterstützt (das ist, wie variadische Argumente Arbeit).
Allerdings ist die letztere Option funktioniert nur, wenn T
a Referenztyp (das heißt kein primitiver Typ wie int
), da nur Referenztypen als Typ-Parameter in den Bereichen Generika verwendet werden können (und T
ist ein Typ-Parameter).
Wenn Sie also int[]
passieren, erhalten Sie T
= int[]
, und Sie Code funktioniert nicht wie erwartet. Aber wenn Sie Array von Referenztyp passieren (zB Integer[]
), erhalten Sie T
= Integer
und alles funktioniert:
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] + " ");
}
Andere Tipps
Versuchen Sie, diese Zeile Code zu Ihrem Test hinzufügen:
List l=Arrays.asList(arr);
System.out.println(l);
Sie werden sehen, Sie drucken ein einzelnes Element List
aus.
Mit Arrays.asList
auf einer primitiven Array Ursache asList
die int[]
als einzelnes Objekt zu behandeln, anstatt ein Array. Es gibt einen List<int[]>
anstelle eines List<Integer>
. So sind Sie im Grunde ein einziges Element List
schlurfend und so wird nichts wirklich neu gemischt.
Beachten Sie, dass einige der Antworten schon gegeben sind falsch, weil asList
gibt eine Liste von der Original-Array unterstützt, wird nichts kopiert -. Alle Änderungen in der ursprünglichen Anordnung reflektiert werden
Das funktioniert nicht, weil der Aufruf von shuffle
auf der List
zurück von Arrays.asList
arbeitet, nicht auf die zugrunde liegende Array. Wenn Sie also über das Array iterieren die Werte auszudrucken, hat sich nichts geändert. Was Sie tun möchten, ist speichern einen Verweis auf die List
von Arrays.asList
zurückgekehrt, und dann ausdrucken die Werte dieser List
(eher als die Werte des Arrays), nachdem Sie es shuffle
.
Speichern Sie die Liste resturned von Arrays.asList und Shuffle, dass ...
List myShuffledList = Arrays.asList(arr);
Collections.shuffle(myShuffledList);