web-dev-qa-db-fra.com

Java Collections.shuffle fait quoi?

Je me suis récemment retrouvé à avoir besoin d'être sûr que ma liste n'était pas en ordre. Hibernate était assez sympa pour le retourner en parfait état. Stupide hibernation, ne lisant pas mon esprit.

J'ai regardé mon Java API et il me dit que sa méthode de lecture aléatoire fait ceci:

Permute aléatoirement la liste spécifiée en utilisant une source aléatoire par défaut.

Étant le curieux george que je suis, je veux savoir ce que cela signifie exactement. Existe-t-il un cours de mathématiques que je peux suivre pour apprendre cela? Puis-je voir le code? Java, que faites-vous à ma liste de tableaux?!?!?

Pour être plus précis, quels concepts mathématiques sont utilisés ici?

40
Stephano

Oui, vous pouvez regarder le code; il fait essentiellement un shuffle de Fisher-Yates . Le voici (merci OpenJDK, et oui pour l'open source :-P):

public static void shuffle(List<?> list, Random rnd) {
    int size = list.size();
    if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
        for (int i=size; i>1; i--)
            swap(list, i-1, rnd.nextInt(i));
    } else {
        Object arr[] = list.toArray();

        // Shuffle array
        for (int i=size; i>1; i--)
            swap(arr, i-1, rnd.nextInt(i));

        // Dump array back into list
        ListIterator it = list.listIterator();
        for (int i=0; i<arr.length; i++) {
            it.next();
            it.set(arr[i]);
        }
    }
}

La méthode de swap:

 private static void swap(Object[] x, int a, int b) {
    Object t = x[a];
    x[a] = x[b];
    x[b] = t;
}
51
Chris Jester-Young

Collections JavaDoc donne quelques informations sur la méthode de shuffle utilisée.

Cette implémentation parcourt la liste en arrière, du dernier élément au second, en échangeant à plusieurs reprises un élément sélectionné au hasard dans la "position actuelle". Les éléments sont sélectionnés au hasard dans la partie de la liste qui va du premier élément à la position actuelle, inclus.

Cela commence donc à la fin et fait reculer la liste. À chaque élément, il s'arrête et échange l'élément actuel avec un élément précédent de la liste. La "source aléatoire par défaut" dans ce cas est probablement un Random objet créé avec une graine par défaut.

6
Bill the Lizard