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

 更新时间:2025年04月10日 08:31:58   作者:索大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生成不重复随机数方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot的@GetMapping路径匹配规则、国际化详细教程

    SpringBoot的@GetMapping路径匹配规则、国际化详细教程

    这篇文章主要介绍了SpringBoot的@GetMapping路径匹配规则、国际化,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2023-11-11
  • Java中static静态变量的初始化完全解析

    Java中static静态变量的初始化完全解析

    static所声明的变量在Java中有一个初始化的先后顺序,带着这个问题接下来我们就来进行Java中static静态变量的初始化完全解析:
    2016-06-06
  • Maven依赖冲突问题及解决过程

    Maven依赖冲突问题及解决过程

    文章主要讨论Maven依赖冲突问题,及提供解决方法,首先描述了依赖冲突现象的nd导致类NoClassDefFoundError的情况;然后介绍了查找冲突包的方法,最后总结了Maven依赖管理的几种策略,包括依赖调解、依赖排除和依赖范围控制;强调了合理配置POM文件的重要性
    2026-04-04
  • Java高性能缓存框架之Caffeine详解

    Java高性能缓存框架之Caffeine详解

    这篇文章主要介绍了Java高性能缓存框架之Caffeine详解,Caffeine是一个基于Java8的高性能缓存框架,号称趋于完美,Caffeine受启发于Guava Cache的API,使用API和Guava是一致的,需要的朋友可以参考下
    2023-12-12
  • idea2020.3配置maven环境并配置Tomcat的详细教程

    idea2020.3配置maven环境并配置Tomcat的详细教程

    这篇文章主要介绍了idea2020.3配置maven环境并配置Tomcat的详细教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • JAVA算法起步之堆排序实例

    JAVA算法起步之堆排序实例

    这篇文章主要介绍了JAVA算法起步之堆排序实例,需要的朋友可以参考下
    2014-02-02
  • Java Hashtable机制深入了解

    Java Hashtable机制深入了解

    HashTable是jdk 1.0中引入的产物,基本上现在很少使用了,但是会在面试中经常被问到。本文就来带大家一起深入了解一下Hashtable,需要的可以参考一下
    2022-09-09
  • Java任务调度的常见实现方法与比较详解

    Java任务调度的常见实现方法与比较详解

    这篇文章主要介绍了Java任务调度的常见实现方法与比较,结合实例形式分析了Java任务调度的四种常见实现方法,使用区别及相关注意事项,需要的朋友可以参考下
    2017-08-08
  • Java中的BigDecimal使用问题小结

    Java中的BigDecimal使用问题小结

    BigDecimal 是 Java 中用于进行精确十进制计算的重要类, 它适用于金融、科学等需要高精度计算的场景,这篇文章让我来详细讲解 Java 中的 BigDecimal 类,包括它的用途、适用场景、以及潜在问题,感兴趣的朋友一起看看吧
    2025-04-04
  • Mybatis如何使用正则模糊匹配多个数据

    Mybatis如何使用正则模糊匹配多个数据

    这篇文章主要介绍了Mybatis如何使用正则模糊匹配多个数据,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01

最新评论