Come randomizzare due ArrayList nello stesso modo?


257

Ho due arraylist fileliste imgListche si relazionavano tra loro, ad esempio "H1.txt" in relazione a "e1.jpg". Come randomizzare automaticamente l'elenco di imgListsecondo la randomizzazione di fileList? Come in Excel, se ordiniamo una determinata colonna, l'altra colonna seguirà automaticamente?

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);

output dopo randomizzazione ad es .:

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

uscita prevista:

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

Risposte:


585

Usa Collections.shuffle()due volte, con due Randomoggetti inizializzati con lo stesso seme:

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

L'uso di due Randomoggetti con lo stesso seme garantisce che entrambi gli elenchi vengano mescolati esattamente nello stesso modo. Ciò consente due raccolte separate.


121

Avvolgili in un'altra classe in modo da poter finire con un singolo array o Listdi quegli oggetti.

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

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

Esempio di utilizzo:

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);

10
Questa è la soluzione Java, orientata agli oggetti. Forse, come dovrebbe essere fatto ... :)
Evan,

22

L'approccio più semplice è incapsulare i due valori insieme in un tipo che ha sia l'immagine che il file. Poi costruire un ArrayListdi che e shuffle esso.

Ciò migliora anche l'incapsulamento, dandoti la proprietà di avere sempre lo stesso numero di file delle immagini automaticamente.

Un'alternativa se davvero non ti piace quell'idea sarebbe quella di scrivere tu stesso il codice shuffle (ci sono molti esempi di shuffle Fisher-Yates modificato in Java, compresi alcuni su Stack Overflow sospetto) e operare su entrambi gli elenchi su lo stesso tempo. Ma consiglio vivamente di seguire l'approccio "migliorare l'incapsulamento".


11

Puoi farlo con le mappe:

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

Questo scorrerà le immagini in ordine casuale.


5

Questo può essere fatto usando il metodo shuffle:

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

4

Invece di avere due array di stringhe, è necessario disporre di un array di una classe personalizzata che contenga le due stringhe.


3

È possibile creare un array contenente i numeri da 0 a 5 e mescolarli. Quindi utilizzare il risultato come mapping di "oldIndex -> newIndex" e applicare questo mapping a entrambi gli array originali.


2

Non sei completamente sicuro di cosa significhi "automaticamente": puoi creare un oggetto contenitore che contenga entrambi gli oggetti:

classe pubblica FileImageHolder {String fileName; String imageName; // TODO: inserisci qui le cose}

Quindi inseriscilo in un elenco di array e randomizza l'elenco di array.

Altrimenti, dovresti tenere traccia di dove ogni elemento si spostava in un elenco e spostarlo anche nell'altro.


2

A meno che non ci sia un modo per recuperare il vecchio indice degli elementi dopo che sono stati mescolati, lo farei in due modi:

A) Crea un altro elenco multi_shuffler = [0, 1, 2, ..., file.size ()] e mescolalo. Passaci sopra per ottenere l'ordine per i tuoi file / elenchi di immagini mescolati.

ArrayList newFileList = new ArrayList (); ArrayList newImgList = new ArrayList (); per (i = 0; i

oppure B) Crea una classe StringWrapper per contenere i nomi di file / immagini e combina le due liste che hai già inserito in una: ArrayList CombinedList;

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.