如何打乱List 或 Array元素的顺序
打乱List或者Array数据元素的顺序,其实就是让集合中的元素变得随机,举个例子,有如下一个Array数据:
其中存储了 1, 2, 3, 4, 5 一共五个元素,经过程序随机排序后得到另外一个随机乱序的数组。
其Java实现代码如下:
public class ArrayRandomUtils {
public static void main(String[] args) {
int[] arr = new int[]{1, 2, 3, 4, 5};
arr = randomArr(arr);
System.out.println(Arrays.toString(arr));
}
public static int[] randomArr(int[] arr) {
int[] arrTemp = new int[5];
int end = arr.length;
Random rad = new Random();
for (int i = 0; i < arr.length; i++) {
int index = rad.nextInt(end);
arrTemp[i] = arr[index];
arr[index] = arr[end - 1];
end--;
}
return arrTemp;
}
}
实现思路如下:
1、随机生成一个原数组长度内的随机整数 index;
2、将随机位置 index 上的元素拷贝到新数组的第 i 个位置;
3、然后,将原数组中第 end(end的初始值为原数组的长度) 个元素拷贝至原数组的第 index 位置;
4、最后,将 end– 相当于原数组的一个元素已经被随机到了新数组中。
处理流程:
Collections 洗牌算法源码
了解了以上数组元素随机打乱的算法之后,再来看一下Collections 的 shuffle 方法的源码就很好理解了。
public static void shuffle(List<?> list) {
Random rnd = r;
if (rnd == null)
r = rnd = new Random();
shuffle(list, rnd);
}
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]);
}
}
}