Java 8通过Random.LongStream()随机选取List元素及流随机抽取相关问题
Java 8 中使用Random.IntStream获取无重复随机元素集合的实现方案
可以实现,目前有两种主流的实现方式,分别适配不同的使用场景:
方案1:内置distinct()去重(适用于取数数量远小于随机数总范围的场景)
- 核心逻辑是借助IntStream自带的
distinct()中间操作过滤重复值,再通过limit()限制需要获取的元素个数,最后装箱转换为目标集合即可。 - 示例代码(从0~99范围内取10个不重复随机数):
import java.util.List; import java.util.Random; import java.util.stream.Collectors; public class DistinctRandomDemo { public static void main(String[] args) { Random random = new Random(); // 随机数范围左闭右开,下例为生成0到99的整数 int minBound = 0; int maxBound = 100; // 需要获取的无重复元素数量 int pickCount = 10; List<Integer> distinctRandoms = random.ints(minBound, maxBound) .distinct() .limit(pickCount) .boxed() .collect(Collectors.toList()); System.out.println(distinctRandoms); } }
- 注意:如果需要获取的元素数量和随机数总范围大小接近,该方案效率会大幅下降,越到后期生成重复随机数的概率越高,会产生大量无效计算。
方案2:随机排序索引实现(适用于取数占比高、或是从现有List中选无重复元素的场景)
- 核心逻辑是先生成目标范围的所有整数/现有List的全部索引,通过随机排序打乱顺序后取前N个,从根源上避免重复值生成。
- 示例代码(从自定义List中随机取3个不重复元素):
import java.util.List; import java.util.Random; import java.util.stream.Collectors; import java.util.stream.IntStream; public class ShufflePickDemo { public static void main(String[] args) { Random random = new Random(); List<String> sourceList = List.of("苹果", "香蕉", "橙子", "葡萄", "西瓜", "芒果"); int pickCount = 3; List<String> pickedItems = IntStream.range(0, sourceList.size()) .boxed() // 随机打乱索引顺序 .sorted((o1, o2) -> random.nextInt(2) - 1) .limit(pickCount) .map(sourceList::get) .collect(Collectors.toList()); System.out.println(pickedItems); } }
- 优势:不会产生无效随机数计算,时间复杂度稳定为O(n),其中n为随机数总范围/源List的长度,不管取数占比多少都能保持稳定性能。
内容的提问来源于stack exchange,提问作者Guy Fawkes
相关产品推荐
相关产品推荐

