最标准、推荐的方式是使用 collections.shuffle() 方法,它基于 fisher-yates 算法,保证均匀随机性,原地操作、时间复杂度 o(n),可选默认或自定义 random 实例。

Java 中对 ArrayList 进行随机打乱顺序,最标准、推荐的方式是使用 Collections.shuffle() 方法。
使用 Collections.shuffle()(最常用)
这是 JDK 内置的、经过充分测试的洗牌算法(基于 Fisher-Yates),能保证均匀随机性,且操作原列表(无需新建)。
- 直接传入 ArrayList 对象即可,无需额外参数
- 默认使用系统默认的随机源(
new Random()),也可传入自定义Random实例用于可重现的随机序列 - 时间复杂度为 O(n),原地操作,空间效率高
示例:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
手动实现 Fisher-Yates 洗牌(了解原理)
如果你需要完全控制随机过程(比如用特定种子、或学习算法),可以手写 Fisher-Yates(也叫 Knuth shuffle):
- 从最后一个元素开始,每次随机选择一个索引(含当前位),与之交换
- 必须只在
[0, i]范围内选,不能选整个列表,否则会破坏均匀性
示例:
Random rand = new Random(42); // 可复现 for (int i = list.size() - 1; i > 0; i--) { int j = rand.nextInt(i + 1); Collections.swap(list, i, j); }注意:避免常见错误
- 不要用
list.sort((a,b) -> Math.random() > 0.5 ? 1 : -1) - 这不是真正随机,且依赖排序算法实现,可能导致结果偏差甚至死循环(如 TimSort 的稳定性要求)
- 不要自己写“随机交换 n 次” —— 简单循环交换固定次数(如 swap 10 次)无法保证均匀分布,也不等价于全排列随机采样
如果需要返回新列表(不修改原 ArrayList)
先复制再洗牌:
ListJava免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










