java数组随机采样核心是生成不重复随机索引,推荐洗牌后截取(collections.shuffle)或random+set去重;允许重复时可用threadlocalrandom.nextint直接生成索引。

Java 中数组实现随机采样,核心是“不重复地随机选几个索引”,再用这些索引取对应元素。关键不在数组本身(它不自带采样方法),而在于借助 Random 或 ThreadLocalRandom 生成合法、无重复的随机下标。
直接随机选索引(适合小样本、允许重复)
如果只要简单随机抽取(允许同一元素被多次选中),只需用 Random 生成 0 到 array.length - 1 范围内的随机整数即可:
- 用
ThreadLocalRandom.current().nextInt(0, array.length)更高效(推荐用于多线程) - 循环调用该方法 n 次,每次取
array[index]就得到 n 个随机样本(可能重复)
不重复随机采样(常用场景)
多数实际需求要求“从数组中随机挑 k 个不同元素”,这时不能简单重复生成索引,否则可能重复。推荐两种可靠方式:
-
洗牌后截取:用
Collections.shuffle()对包装后的列表打乱,再取前 k 个。适用于原数组可转为List且不介意临时拷贝 - 蓄水池采样:适合大数据流或内存受限场景,但对普通数组略显复杂;一般情况更推荐前一种
示例(不重复采样 3 个):
List
Collections.shuffle(list);
String[] sample = list.subList(0, Math.min(3, list.size())).toArray(new String[0]);
用 Random + Set 去重(灵活控制)
如果不想改动原数组或避免创建新列表,可用 Set 记录已选索引,直到凑够 k 个为止:
- 初始化空
HashSet<integer></integer> - 循环生成随机索引,成功添加进 set 后才计数,直到 size 达到 k
- 再遍历 set,按索引取数组元素
注意:当 k 接近数组长度时,碰撞概率升高,效率下降;此时洗牌法更稳定。
一行流式写法(Java 8+)
借助 Stream 可简洁实现不重复采样(本质仍是先转 List 再 shuffle):
String[] sample = Arrays.stream(arr).collect(Collectors.collectingAndThen(
Collectors.toList(),
list -> { Collections.shuffle(list); return list; }
))
.stream()
.limit(k)
.toArray(String[]::new);
语义清晰,但要注意 limit(k) 在 shuffle 后才生效,才能保证真正随机。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











