java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java生成不重复随机数方法

Java中生成不重复随机数的四种方法举例详解

作者:索大l

在Java编程中获取随机数是常见的需求,这篇文章主要介绍了Java中生成不重复随机数的四种方法,文中通过代码介绍的非常详细,需要的朋友可以参考下

摘要:

在Java开发中,生成不重复的随机数是常见的需求,例如抽奖、随机抽样等场景。本文提供四种高效实现方案,涵盖不同范围与数据量的场景,并附完整代码示例。

 一、需求场景分析

生成不重复随机数的核心问题是“如何避免重复”。根据不同的范围与生成数量,我们需要选择不同的策略:

-范围小且需全覆盖(如1~100):适合预生成后打乱顺序。

-范围大但数量少(如1~100000取10个):适合动态生成并去重。

-中等范围动态生成(如1~1000取100个):适合逐步移除已选值。

 二、具体实现方法

方法1:使用`Collections.shuffle`打乱顺序

适用场景:固定范围内生成所有值的不重复序列(如洗牌算法)。

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ShuffleDemo {
    public static void main(String[] args) {
        int min = 1, max = 100;
        List<Integer> numbers = new ArrayList<>();
        for (int i = min; i <= max; i++) {
            numbers.add(i);
        }
        Collections.shuffle(numbers); // 关键:随机打乱顺序
        
        // 获取前10个不重复值
        numbers.stream().limit(10).forEach(System.out::println);
    }
}

优点:时间复杂度O(n),效率极高。  

缺点:需预先生成所有值,内存占用高。

方法2:通过`Set`去重

适用场景:从大范围中生成少量随机数(如从1~100000中取10个)。

import java.util.HashSet;
import java.util.Random;
import java.util.Set;

public class SetDemo {
    public static void main(String[] args) {
        int min = 1, max = 100_000, count = 10;
        Set<Integer> uniqueNumbers = new HashSet<>();
        Random random = new Random();

        while (uniqueNumbers.size() < count) {
            int num = random.nextInt(max - min + 1) + min;
            uniqueNumbers.add(num); // Set自动去重
        }

        uniqueNumbers.forEach(System.out::println);
    }
}

优点:内存占用低。  

缺点:生成数量接近范围上限时性能骤降。

方法3:动态移除已选值

适用场景:中等范围动态生成(如从1~1000中取500个)。

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class PoolDemo {
    public static void main(String[] args) {
        int min = 1, max = 1000, count = 10;
        List<Integer> pool = new ArrayList<>();
        for (int i = min; i <= max; i++) {
            pool.add(i);
        }

        Random random = new Random();
        for (int i = 0; i < count; i++) {
            int index = random.nextInt(pool.size());
            int num = pool.remove(index); // 移除已选值
            System.out.println(num);
        }
    }
}

优点:避免重复碰撞问题。  

缺点:频繁操作List可能导致性能下降。

方法4:Java 8 Stream API(简洁写法)

适用场景:快速生成少量不重复值。

import java.util.Random;
import java.util.stream.IntStream;

public class StreamDemo {
    public static void main(String[] args) {
        int min = 1, max = 100, count = 10;
        Random random = new Random();

        IntStream.generate(() -> random.nextInt(max - min + 1) + min)
                .distinct()     // 去重
                .limit(count)   // 限制数量
                .forEach(System.out::println);
    }
}

优点:代码简洁,适合函数式编程。  

缺点:不适用于生成数量接近范围上限的场景。

三、性能与注意事项

1. 范围与数量的关系**:必须满足 `count ≤ (max - min + 1)`,否则代码会陷入死循环。

2. 线程安全:多线程环境下建议使用 `ThreadLocalRandom`。

3. 性能对比:

   - 最优场景:`Collections.shuffle` > 动态移除 > Set > Stream

   - 最差场景:(如生成999/1000个值):动态移除 > `Collections.shuffle` > Set > Stream

四、总结

| 方法                | 适用场景                                            | 推荐指数 |

| `Collections.shuffle`  | 小范围全覆盖                            | ⭐⭐⭐⭐   |
| `Set`去重                   | 大范围取少量值                        | ⭐⭐⭐     |
| 动态移除                   | 中等范围动态取值                     | ⭐⭐⭐⭐   |
| Stream API               | 代码简洁且数量远小于范围       | ⭐⭐      |

建议根据实际需求选择最合适的方法,避免因算法选择不当导致性能问题。

到此这篇关于Java中生成不重复随机数的四种方法的文章就介绍到这了,更多相关Java生成不重复随机数方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文