Wie werden zwei ArrayLists auf dieselbe Weise randomisiert?

257

Ich habe zwei Arraylist filelistund imgListwelche miteinander in Beziehung, zB „h1.txt“ im Zusammenhang mit „e1.jpg“. Wie kann die Liste imgListnach der Randomisierung von automatisch randomisiert werden fileList? Wenn wir wie in Excel eine bestimmte Spalte sortieren, folgt automatisch die andere Spalte?

String [] file = {"H1.txt","H2.txt","H3.txt","M4.txt","M5.txt","M6.txt"};
ArrayList<String> fileList = new ArrayList<String>(Arrays.asList(file));

String [] img = {"e1.jpg","e2.jpg","e3.jpg","e4.jpg","e5.jpg","e6.jpg"};
ArrayList<String> imgList = new ArrayList<String>(Arrays.asList(img));

//randomized files
Collections.shuffle(fileList);

Ausgabe nach Randomisierung zB:

fileList = {"M4.txt","M6.txt","H3.txt","M5.txt","H2.txt","H1.txt"};

beabsichtigte Ausgabe:

 imgList = {"e4.jpg","e6.jpg","e3.jpg","e5.jpg","e2.jpg","e1.jpg"};
Jessy
quelle

Antworten:

585

Verwenden Sie Collections.shuffle()zweimal mit zwei RandomObjekte mit demselben Samen initialisiert:

long seed = System.nanoTime();
Collections.shuffle(fileList, new Random(seed));
Collections.shuffle(imgList, new Random(seed));

Durch die Verwendung von zwei RandomObjekten mit demselben Startwert wird sichergestellt, dass beide Listen auf genau dieselbe Weise gemischt werden. Dies ermöglicht zwei separate Sammlungen.

Michael Borgwardt
quelle
121

Wickeln Sie sie in eine andere Klasse ein, damit Sie ein einzelnes Array oder Listeines dieser Objekte erhalten.

public class Data {
    private String txtFileName;
    private String imgFileName;

    // Add/generate c'tor, getter/setter, equals, hashCode and other boilerplate.
}

Anwendungsbeispiel:

List<Data> list = new ArrayList<Data>();
list.add(new Data("H1.txt", "e1.jpg"));
list.add(new Data("H2.txt", "e2.jpg"));
// ...

Collections.shuffle(list);
BalusC
quelle
10
Dies ist die objektorientierte Java-Lösung. Vielleicht, wie es gemacht werden soll ... :)
Evan
22

Der einfachste Ansatz besteht darin, die beiden Werte zu einem Typ zusammenzufassen, der sowohl das Bild als auch die Datei enthält. Dann bauen ein ArrayListvon , dass sie und mischen.

Dies verbessert auch die Kapselung und gibt Ihnen die Eigenschaft, dass Sie automatisch immer die gleiche Anzahl von Dateien wie Bilder haben.

Eine Alternative, wenn Sie diese Idee wirklich nicht mögen, wäre, den Shuffle-Code selbst zu schreiben (es gibt viele Beispiele für einen modifizierten Fisher-Yates-Shuffle in Java, einschließlich mehrerer auf Stack Overflow, wie ich vermute) und einfach beide Listen unter zu bearbeiten die selbe Zeit. Ich würde jedoch dringend empfehlen, den Ansatz "Verkapselung verbessern" zu wählen.

Jon Skeet
quelle
11

Sie können dies mit Karten tun:

Map<String, String> fileToImg:
List<String> fileList = new ArrayList(fileToImg.keySet());
Collections.shuffle(fileList);
for(String item: fileList) {
    fileToImf.get(item);
}

Dadurch werden die Bilder in zufälliger Reihenfolge durchlaufen.

jjnguy
quelle
5

Dies kann mit der Shuffle-Methode erfolgen:

private List<Integer> getJumbledList() {
     List<Integer> myArrayList2 = new ArrayList<Integer>();
        myArrayList2.add(8);
        myArrayList2.add(4);
        myArrayList2.add(9);
        Collections.shuffle(myArrayList2);
        return myArrayList2;
Rohit Goyal
quelle
4

Anstatt zwei Arrays von Strings zu haben, sollten Sie ein Array einer benutzerdefinierten Klasse haben, die Ihre zwei Strings enthält.

EboMike
quelle
3

Sie können ein Array mit den Zahlen 0 bis 5 erstellen und diese mischen. Verwenden Sie das Ergebnis dann als Zuordnung von "oldIndex -> newIndex" und wenden Sie diese Zuordnung auf Ihre beiden ursprünglichen Arrays an.

Mark Byers
quelle
2

Nicht ganz sicher, was Sie unter "automatisch" verstehen - Sie können ein Containerobjekt erstellen, das beide Objekte enthält:

öffentliche Klasse FileImageHolder {String fileName; String imageName; // TODO: füge hier etwas ein}

Und dann füge das in eine Array-Liste ein und randomisiere diese Array-Liste.

Andernfalls müssten Sie verfolgen, wo sich jedes Element in einer Liste bewegt hat, und es auch in die andere verschieben.

Aperkins
quelle
2

Wenn es keine Möglichkeit gibt, den alten Index der Elemente nach dem Mischen abzurufen, kann ich dies auf zwei Arten tun:

A) Erstellen Sie eine weitere Liste multi_shuffler = [0, 1, 2, ..., file.size ()] und mischen Sie sie. Führen Sie eine Schleife durch, um die Reihenfolge für Ihre gemischten Datei- / Bildlisten zu erhalten.

ArrayList newFileList = new ArrayList (); ArrayList newImgList = new ArrayList (); für (i = 0; i

oder B) Erstellen Sie eine StringWrapper-Klasse, die die Datei- / Bildnamen enthält, und kombinieren Sie die beiden bereits vorhandenen Listen zu einer: ArrayList kombinierte Liste;

Ajwood
quelle