JDK Collections.shuffle(List<?> list, Random rnd)源码分析
时间: 2024-03-09 16:50:52 浏览: 116
好的,我会为您分析该源码。
首先,让我们来看看该方法的作用:将列表中的元素随机排列。它接受两个参数:一个是要随机排列的列表,另一个是用于随机化的随机数生成器。如果不提供随机数生成器,则使用默认的随机数生成器。
该方法的源码如下:
```java
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]);
}
}
}
private static void swap(Object[] arr, int i, int j) {
Object tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
@SuppressWarnings({"rawtypes", "unchecked"})
private 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)));
}
```
该方法首先检查列表的大小是否小于一个阈值(默认为5)。如果是,则使用传统的交换算法来随机排列列表中的元素。如果列表实现了RandomAccess接口(例如ArrayList),则使用传统的交换算法来随机排列列表中的元素。
如果列表大小大于阈值,并且不是RandomAccess的实例(例如LinkedList),则首先将列表转换为数组。然后对数组中的元素进行随机排列,最后将数组中的元素转换回列表。
两个swap()方法用于交换数组或列表中的元素。
总的来说,该方法使用了经典的洗牌算法来随机排列列表中的元素。
阅读全文