Collections.shuffle方法通过Fisher-Yates算法实现,使用默认或自定义Random实例打乱List顺序,确保均匀随机排列,适用于可重现测试与多场景需求。

Java中的
Collections.shuffle
List
Collections.shuffle
List
public static void shuffle(List<?> list)
java.util.Random
List
public static void shuffle(List<?> list, Random rnd)
java.util.Random
无论使用哪个版本,
shuffle
List
List
举个例子,如果你有一个包含数字1到5的列表,调用
shuffle
立即学习“Java免费学习笔记(深入)”;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public class ShuffleExample {
public static void main(String[] args) {
// 示例1: 使用默认随机源
List<String> cards = new ArrayList<>();
for (int i = 1; i <= 5; i++) {
cards.add("Card " + i);
}
System.out.println("原始列表: " + cards);
Collections.shuffle(cards);
System.out.println("默认打乱后: " + cards);
// 示例2: 使用自定义随机源(固定种子,用于可重现性)
List<Integer> numbers = new ArrayList<>();
for (int i = 1; i <= 5; i++) {
numbers.add(i);
}
System.out.println("原始数字列表: " + numbers);
// 使用固定种子,每次运行结果相同
Random reproducibleRandom = new Random(12345L);
Collections.shuffle(numbers, reproducibleRandom);
System.out.println("固定种子打乱后: " + numbers);
// 再次使用相同种子,验证结果一致
reproducibleRandom = new Random(12345L);
List<Integer> anotherNumbers = new ArrayList<>();
for (int i = 1; i <= 5; i++) {
anotherNumbers.add(i);
}
Collections.shuffle(anotherNumbers, reproducibleRandom);
System.out.println("再次固定种子打乱后: " + anotherNumbers);
}
}谈到
Collections.shuffle
shuffle
具体步骤可以这样理解:
n-1
1
j
j
0
i
i
i
j
这种方法确保了每个元素在每个位置都有相等的概率出现,从而生成一个均匀分布的随机排列。它的时间复杂度是O(N),其中N是列表的大小,效率非常高。
至于随机数的来源,默认情况下
Collections.shuffle
java.util.Random
Random
Random
java.security.SecureRandom
Collections.shuffle
SecureRandom
在使用
Collections.shuffle
从性能角度看,
Collections.shuffle
shuffle
LinkedList
ArrayList
LinkedList
get(j)
set(j, element)
shuffle
ArrayList
RandomAccess
List
shuffle
再说说线程安全。
Collections.shuffle
List
List
shuffle
shuffle
List
ConcurrentModificationException
那么,如何处理呢?
如果每个线程处理自己的List
如果多个线程需要共享同一个List
shuffle
synchronized
shuffle
java.util.concurrent.locks.Lock
List<String> sharedList = Collections.synchronizedList(new ArrayList<>());
// ... 添加元素到sharedList
// 在多线程环境中,需要额外的同步
synchronized (sharedList) {
Collections.shuffle(sharedList);
}或者,如果你使用了
java.util.ArrayList
shuffle
shuffle
List<String> myUnsynchronizedList = new ArrayList<>();
// ... 添加元素
Object lock = new Object(); // 或者直接用myUnsynchronizedList作为锁对象
synchronized (lock) {
Collections.shuffle(myUnsynchronizedList);
}此外,如果你传入了自定义的
Random
Random
java.util.Random
Random
java.util.concurrent.ThreadLocalRandom
Random
有时候,我们需要的“随机”并不是真正意义上的不可预测,而是希望在特定条件下能够重现相同的随机序列。这在测试、模拟或者调试时非常有用。
Collections.shuffle
java.util.Random
实现可重现的随机序列: 核心在于
Random
Random
long
Random(long seed)
seed
seed
Random
Random
Random
long
Random
Collections.shuffle
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public class ReproducibleShuffle {
public static void main(String[] args) {
long fixedSeed = 98765L; // 这是一个固定的种子
List<String> items1 = new ArrayList<>();
items1.add("A"); items1.add("B"); items1.add("C"); items1.add("D"); items1.add("E");
List<String> items2 = new ArrayList<>();
items2.add("A"); items2.add("B"); items2.add("C"); items2.add("D"); items2.add("E");
System.out.println("原始列表1: " + items1);
System.out.println("原始列表2: " + items2);
// 使用相同的种子打乱列表1
Random random1 = new Random(fixedSeed);
Collections.shuffle(items1, random1);
System.out.println("使用固定种子打乱列表1: " + items1);
// 再次使用相同的种子打乱列表2
Random random2 = new Random(fixedSeed); // 重新创建一个Random实例,使用相同的种子
Collections.shuffle(items2, random2);
System.out.println("使用相同固定种子打乱列表2: " + items2);
// 结果会是一样的,因为种子相同
}
}在我看来,这种能力在单元测试中特别有用。比如,你测试一个依赖于随机排序的算法,如果每次测试结果都不同,调试起来会很麻烦。通过固定种子,你可以确保每次运行测试时,
shuffle
自定义随机源: 除了固定种子,传入自定义
Random
java.util.Random
java.security.SecureRandom
SecureRandom
Random
SecureRandom
Collections.shuffle
shuffle
Random
Random
Random
总的来说,
Collections.shuffle
以上就是Java中Collections.shuffle方法的应用的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号