今天在做一个Java项目, 用到了使用一组不重复的随机数问题, 不管怎么做随机数里面总有几个是重复的.

于是上网去找资料, 在网上找到的资料中大部分都是一个思路:

网上的思路一:(性能不理想)

先生成一个随机数, 然后在生成下一个随机数的时候和以前的随机数进行匹配, 如果里面有当前生成的随机数, 那么重新去生成, 直到之前所生成的随机数组中没有当前所生成的那个数字为止. 这样做虽然能实现生成一组不重复的随机数, 但是性能不是很理想, 假如我们需要生成10个数字, 在生成第一的时候, 不用匹配, 在生成第二的时候和第一个匹配, 由于是随机数, 那么他的重复几率为 1 /10, 生成第三个的时候和第一个第二个进行匹配, 他的重复几率为 2 /10, 在生成最后一个的时候要和之前的前9个进行匹配, 那么最后一个生成的数就有 9 / 10 的几率和之前的数字重复, 由于10分之9的几率已经接近了1, 也就是说, 生成随机数的时候越往后重复的几率越接近1, 需要重新生成的次数越多,性能越差.

我分析的思路二:

我的思路是, 只生成一次随机数作为模板, 里面是有重复的, 在生成的过程中把这组数字按顺序放到一个集合里, 然后把这组随机数和集合中的数进行匹配, 把在集合中存在的那些随机数给移除掉, 那么集合中就剩下了随机数组中没有的数字了, 最后把随机数组中两个重复的最后一个数字换成集合中的第一个数字, 再把集合的第一个移除掉, 如此类推, 直到集合中的数字用完为止.

    public static void main(String[] args) {
// TODO Auto-generated method stub //网上方法获取不重复随机数
testA(10000);
//自定义方法获取不重复随机数
testB(10000);
} //自定义方法获取不重复随机数
private static void testB(int sz){
long startTime=System.currentTimeMillis(); //开始测试时间
Random rd = new Random();
int[] rds = new int[sz];//随机数数组
int n = 0;//序号
List<Integer> lst = new ArrayList<Integer>();//存放有序数字集合
//获取随机数数组, 里面有重复数字
while (n < rds.length) {
lst.add(n);
rds[n++] = (int)(rd.nextFloat() * sz);
}
//把随机数和有序集合进行匹对, 把随机数在集合出现的数字从集合中移除掉.
for (int i = 0; i < rds.length; i++) {
for (int j = 0; j < lst.size(); j++) {
if (rds[i] == lst.get(j)) {
lst.remove(j);
break;
}
}
}
//把数组中重复的第二个数字用集合的第一个数字替换掉, 并移除掉数组的第一个数字
for (int i = 0; i < rds.length; i++) {
for (int j = 0; j < rds.length; j++) {
if (i != j && rds[i] == rds[j]) {
rds[j] = lst.get(0);
lst.remove(0);
break;
}
}
}
//得到的 rds 数组就是不重复的随机数组
long endTime=System.currentTimeMillis(); //获取结束时间
System.out.println("自定义代码运行时间: "+(endTime-startTime)+"ms");
}
//网上方法获取不重复随机数
private static void testA(int sz){
long startTime=System.currentTimeMillis(); //开始测试时间
Random random = new Random();
int a[] = new int[sz];
for (int i = 0; i < a.length; i++) {
a[i] = random.nextInt(sz);
for (int j = 1; j < i; j++) {
while (a[i] == a[j]) {//如果重复,退回去重新生成随机数
i--;
}
}
}
long endTime=System.currentTimeMillis(); //获取结束时间
System.out.println("网上思路代码运行时间: "+(endTime-startTime)+"ms");
}

当测试数字越大越能体现出效果.

以上有不足的地方还请大家见谅!

论 Java 中获取一组不重复的随机数之性能问题的更多相关文章

  1. js获取一组不重复的随机数的方法

    一.基本思路: 建立一个数组存放所有可以取到的值,每次从该数组中随机取走一个,放到新的数组中,直到完成. 二.实现方法 1.方法一: (1)创建一个数组arr,数组元素为所有可能出现元素的集合: (2 ...

  2. JAVA中获取当前系统时间及格式转换

    JAVA中获取当前系统时间   一. 获取当前系统时间和日期并格式化输出: import java.util.Date;import java.text.SimpleDateFormat; publi ...

  3. Java中获取键盘输入值的三种方法

    Java中获取键盘输入值的三种方法     Java程序开发过程中,需要从键盘获取输入值是常有的事,但Java它偏偏就没有像c语言给我们提供的scanf(),C++给我们提供的cin()获取键盘输入值 ...

  4. JAVA中获取路径

    内容来自于snannan_268 关键字: java中获取路径 JAVA中获取路径: 1.jsp中取得路径:   以工程名为TEST为例: (1)得到包含工程名的当前页面全路径:request.get ...

  5. java中获取日期和时间的方法总结

    1.获取当前时间,和某个时间进行比较.此时主要拿long型的时间值. 方法如下:  要使用 java.util.Date .获取当前时间的代码如下 Date date = new Date(); da ...

  6. JAVA中获取当前系统时间

    一. 获取当前系统时间和日期并格式化输出: import java.util.Date;import java.text.SimpleDateFormat; public class NowStrin ...

  7. java中获取路径中的空格处理(%20)问题

    在java中获取文件路径的时候,有时候会获取到空格,但是在中文编码环境下,空格会变成“%20”从而使得路径错误. 解决办法: String path = Parameter.class.getReso ...

  8. java中获取系统属性以及环境变量

    java中获取系统属性以及环境变量 System.getEnv()和System.getProperties()的差别 从概念上讲,系统属性 和环境变量 都是名称与值之间的映射.两种机制都能用来将用户 ...

  9. JAVA中获取当前运行的类名,方法名,行数

    JAVA中获取当前运行的类名,方法名,行数 public static String getTraceInfo(){ StringBuffer sb = new StringBuffer(); Sta ...

随机推荐

  1. 导出数据到excel

    Protected Sub cmdOrderExport_Click(ByVal sender As Object, ByVal e As EventArgs) Handles cmdOrderExp ...

  2. 【HDOJ】2440 Watch out the Animal

    刚开始学随机算法,凸包+模拟退火. /* 2440 */ #include <iostream> #include <cstdio> #include <cstring& ...

  3. 维基百科上—数据仓库、数据挖掘、OLAP三者之间的区别

    数据仓库可以作为数据挖掘和OLAP等分析工具的资料来源,由于存放于数据仓库中的资料,必需经过筛选与转换,因此可以避免分析工具使用错误的资料,而得到不正确的分析结果. 数据挖掘和OLAP同为分析工具,其 ...

  4. Python中利用xpath解析HTML

    在进行网页抓取的时候,分析定位html节点是获取抓取信息的关键,目前我用的是lxml模块(用来分析XML文档结构的,当然也能分析html结构), 利用其lxml.html的xpath对html进行分析 ...

  5. [Design Pattern] Filter Pattern 简单案例

    Filter Pattern,即过滤模式,通过不同的过滤标准,或者低耦合将过滤标准组合在一起,对一组对象进行过滤,属于结构类的设计模式. 下面是一个过滤模式的简单案例. Criteria 定义过滤接口 ...

  6. Maven搭建环境(Linux& Windows)

    Linux下安装Maven 1.前提条件: 1)下载并安装好JDK .在终端输入命令“java -version”,如果出现类似如下信息说明JDK安装成功. $ java -version java ...

  7. SSLStrip 的未来 —— HTTPS 前端劫持

    前言 在之前介绍的流量劫持文章里,曾提到一种『HTTPS 向下降级』的方案 —— 将页面中的 HTTPS 超链接全都替换成 HTTP 版本,让用户始终以明文的形式进行通信. 看到这,也许大家都会想到一 ...

  8. Oracle 数据库基本操作——表操作:查询

    目录: 1.基本查询 2.多表查询 3.多行查询 4.集合查询 2.连接 3.嵌套查询 1.基本查询 语法: select column|others{,columnName|others} from ...

  9. Oracle V$SESSION

    SADDR session address SID session identifier 常用于链接其他列 SERIAL# SID有可能会重复,当两个session的SID重复时,SERIAL#用来区 ...

  10. 天圆地方&#183; 围棋界的盲棋天才 -- 鲍云

    "鲍云是我心目中继 本因坊秀策,吴清源.武宫正树后第四个我最喜欢的棋手. " 说到盲棋,棋迷们首先想到的绝对是柳大华,外号"东方电脑"的他创造过中国象棋1对19 ...