利用Collections工具类将集合随机打乱

List<Student> studentList = new ArrayList<>();
Student student = new Student("zhangshan", "java", 80);
Student student1 = new Student("lisi", "c", 90);
Student student2 = new Student("zhaoliu", "C++", 70);
Student student3 = new Student("wanger", ".net", 75);
Student student4 = new Student("xiaoming", "python", 76);
Student student5 = new Student("cuihua", "Go", 85);

studentList.add(student);
studentList.add(student1);
studentList.add(student2);
studentList.add(student3);
studentList.add(student4);
studentList.add(student5);

// 正常遍历输出
studentList.forEach(s -> System.out.println(s.getName()));
System.out.println("=============================");
// 打乱之后遍历输出
Collections.shuffle(studentList);
studentList.forEach(s -> System.out.println(s.getName()));


// 正常输出结果
zhangshan
lisi
zhaoliu
wanger
xiaoming
cuihua
=============================
// 打乱之后输出结果
xiaoming
zhangshan
wanger
lisi
zhaoliu
cuihua

查看Collections.shuffle(studentList)源码如下:

public static void shuffle(List<?> list) {
    Random rnd = r;
    if (rnd == null)
        r = rnd = new Random(); // harmless race.
    shuffle(list, rnd);
}

private static Random r;

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
        // instead of using a raw type here, it's possible to capture
        // the wildcard but it will require a call to a supplementary
        // private method
        ListIterator it = list.listIterator();
        for (int i=0; i<arr.length; i++) {
            it.next();
            it.set(arr[i]);
        }
    }
}

public static void swap(List<?> list, int i, int j) {
    // instead of using a raw type here, it's possible to capture
    // the wildcard but it will require a call to a supplementary
    // private method
    final List l = list;
    l.set(i, l.set(j, l.get(i)));
}

/**
 * Swaps the two specified elements in the specified array.
 */
private static void swap(Object[] arr, int i, int j) {
    Object tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}

核心思想就是用random生成一个在list大小范围内的随机数,然后随机交换各个元素的位置。

原文地址:https://www.cnblogs.com/jasonboren/p/13856340.html