web-dev-qa-db-fra.com

Comment randomiser deux ArrayLists de la même manière?

J'ai deux arraylist filelist et imgList qui se sont reliés, par ex. "H1.txt" est lié à "e1.jpg". Comment randomiser automatiquement la liste de imgList en fonction de la randomisation de fileList? Comme dans Excel, si nous trions certaines colonnes, l'autre colonne suivra automatiquement?

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

sortie après randomisation, par exemple:

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

sortie prévue:

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

Utilisez Collections.shuffle() deux fois, avec deux objets Random initialisés avec le même germe:

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

L'utilisation de deux objets Random avec la même graine garantit le brassage des deux listes exactement de la même manière. Cela permet deux collections distinctes.

575
Michael Borgwardt

Les envelopper dans une autre classe afin que vous puissiez vous retrouver avec un seul tableau ou List de ces objets.

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

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

Exemple d'utilisation:

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

L'approche la plus simple consiste à encapsuler les deux valeurs ensemble dans un type contenant à la fois l'image et le fichier. Construisez ensuite une ArrayList de that ​​et mélangez-la.

Cela améliore également l'encapsulation, en vous donnant la propriété de toujours avoir automatiquement le même nombre de fichiers que d'images.

Une alternative si vous vraiment ​​n'aimez pas cette idée serait d'écrire vous-même le code de mélange (il existe de nombreux exemples de modification de Fisher-Yates en Java, y compris plusieurs sur Stack Overflow je soupçonne) et juste opérer sur les deux listes en même temps. Mais je recommanderais fortement d’utiliser l’approche "améliorer l’encapsulation".

22
Jon Skeet

Vous pouvez le faire avec des cartes:

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

Cela va parcourir les images dans l'ordre aléatoire.

9
jjnguy

Ceci peut être fait en utilisant la méthode 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;
5
Rohit Goyal

Au lieu d'avoir deux tableaux de chaînes, créez un tableau d'une classe personnalisée contenant vos deux chaînes.

4
EboMike

Vous pouvez créer un tableau contenant les nombres de 0 à 5 et les mélanger. Utilisez ensuite le résultat comme mappage de "oldIndex -> newIndex" et appliquez ce mappage à vos deux tableaux d'origine.

3
Mark Byers

Pas tout à fait sûr de ce que vous entendez par "automatiquement" - vous pouvez créer un objet conteneur qui contient les deux objets:

classe publique FileImageHolder {String fileName; String imageName; // TODO: insérer des trucs ici}

Et mettez ensuite cela dans une liste de tableaux et randomisez cette liste.

Sinon, vous devrez garder une trace de l'endroit où chaque élément a été déplacé dans une liste et le déplacer également dans l'autre.

2
aperkins

À moins qu'il soit possible de récupérer l'ancien index des éléments après leur brassage, je le ferais de deux manières:

A) Créez une autre liste multi_shuffler = [0, 1, 2, ..., file.size ()] et mélangez-la. Boucle dessus pour obtenir la commande de tes listes de fichiers/images mélangées.

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

ou B) Créez une classe StringWrapper pour contenir les noms de fichier/image et combinez les deux listes que vous avez déjà en une seule: ArrayList combinationList;

2
ajwood