<%@ page contentType="text/html; charset=gb2312"%> JAVA基础:随机整数的生成
网站公告:   ◆北天JAVA技术网热情为java爱好者服务,本网内容包括JAVA(JSP、servlet、EJB、webservice、j2ee、javabean、应用服务器、JavaScript),数据库(MYSQL、SQL Server、Sybase、Oracle、DB2、数据库综合知识),设计研究(设计模式、Struts、Spring、Hibernate、设计框架、设计综合知识),WEB2.0新技术(主要介绍AJAX),以及各种技术的入门、实例、例子等等,欢迎各位多来坐坐!◆  诚邀各位JAVA爱好者加盟!◆  本网站内容丰富,更新快,保证每周20篇以上!  
加入收藏
设为首页
联系站长
承接项目
  相关资源:网站首页 | 免费培训学院 | 技术论坛 | JAVA聊天室 | 作家专栏 | 开发工具 | 认证考试 | 会员俱乐部
  JAVA技术初学者园地 | jsp与servlet | javascript | Java源代码 | EJB | web service | 应用服务器 | JAVA综合知识
  设计研究设计模式 | 设计框架 | Struts | Spring | Hibernate | 开源项目 | 面向对象设计 | 设计综合知识
  数 据 库MYSQL | SQL Server | Sybase | Oracle | DB2 | Informix | Access | 数据库综合知识
  其他资源:AJAX新技术 | 网站开发 | ERP软件 | OA办公软件 | 商业智能BI | 开发综合知识 | 承接项目 | 项目试用

 
 
JAVA基础:随机整数的生成
     发布者: 发布时间:2006-12-30

使用Java 2 SDK基础类库产生随机数的方法很多。但是如果你跟不上这些类库的更新脚步,你有可能正在使用的是一种低效的随机数生成机制,更糟糕的是:你有可能得到的不是均匀分布的随机数。本文将向你展示一种较为可靠的随机数生成方法,同时与其他方法进行比较。

自从JDK最初版本发布起,我们就可以使用java.util.Random类产生随机数了。在JDK1.2中,Random类有了一个名为nextInt()的方法:
public int nextInt(int n)
给定一个参数n,nextInt(n)将返回一个大于等于0小于n的随机数,即:0 &lt;= nextInt(n) &lt; n。

你所要做的就是先声明一个Random的对象,在调用其nextInt(n)函数以返回随机值。

这里有个示例,下面的代码段将生成很多随机数并输出它们的平均值:

int count = 1000000;
int range = Integer.MAX_VALUE / 3 * 2;
double sum = 0;
Random rand = new Random();
for (int i=0; i&lt;count; i++) {
sum += rand.nextInt(range);
}
System.out.println(sum/count);

执行了1000000次循环之后,得到的平均值基本上就处于随机数范围的中点(midpoint)。

到目前为止,事情还并不复杂,但是我们会问为什么要使用nextInt(n)?考虑一下的随机数生成方法:
(1)使用老的方法nextInt(),没有制定数值范围
(2)用Math.abs()静态函数得到(1)中产生值的绝对值
(3)对(2)的结果进行取模运算(%),得到期望范围类的值

我们说nextInt(n)要比上述方法更好,为什么呢?参考以下的代码段:

sum = 0;
for (int i=0; i&lt;count; i++) {
sum += Math.abs(rand.nextInt()) % range;
}
System.out.println(sum/count);

不难发现,每次循环都多出了几步运算。事实上,这种随机数生成的方法存在着以下三个问题:

首先,nextInt()返回的值是趋于均匀分布在Integer.MIN_VALUE 和 Integer.MAX_VALUE之间的。如果你取Integer.MIN_VALUE的绝对值,得到的仍然不是一个正数。事实上,Math.abs(Integer.MIN_VALUE)等于Integer.MIN_VALUE。因此,存在着这样一种情况(虽然很少见):rand.nextInt()=Integer.MIN_VALUE,经过取绝对值Math.abs(rand.nextInt())之后,得到是一个负数。这种几率为 1/(2^31),在我们的测试中不太可能发生——循环次数只有1000000次。

其次,当你对nextInt()取模时,你使结果的随机性大打折扣。随机数中较小的值出现的几率更大一些。这就是众所周知的伪随机数生成,因此我们不是用取模的方法。

最后,也可能是最糟糕的:随机数不是均匀分布。如果你执行了上述的两段代码,第一段代码的结果将会大于715,000,000,考虑到数值范围的中点(midpoint)是715,827,882,所以这是一个可以接受的结果。然而,你会吃惊的发现第二段代码得到的平均值肯定不会超过600,000,000。

为何第二段代码的结果会如此的偏差?纠其本质,问题出在数值分布的不均匀。当你进行取模运算时,你将过大的数转换成了较小的。这使得较小的数更容易产生。

使用nextInt(range)将会解决上述的三个问题。

还有一种随机数生成方法——使用Math.random()。这个方法的效果如何?

sum = 0;
for (int i=0; i&lt;count; i++) {
sum += (int)(Math.random() * range);
}
System.out.println(sum/count);

很好,使用random()不会碰到nextInt()的麻烦。你不会得到负数返回值,没有使用取模运算,值分布也是均匀的。还有什么问题吗?你有没有考虑到Math.random()使用了浮点运算,而nextInt()和nextInt(range)只有整数操作?Math.random()可能会慢上四倍。再加上从浮点到整数的类型转换,整个运算将会更慢。

好了,经过一番比较,我们发现使用nextInt(range)生成随机数更为有效,因为它避免了其他方法的种种弊端。

最后再给出一段代码,通过测试可以比较本文提到的几种随机数生成方法。

import java.util.*;
import java.text.*;

public class RandomTest {
public static void main(String args[]) {
NumberFormat nf = NumberFormat.getInstance();
int count = 1000000;
int range = Integer.MAX_VALUE / 3 * 2;
System.out.println("Midpoint: " + nf.format(range/2));
double sum = 0;
Random rand = new Random();

for (int i=0; i&lt;count; i++) {
sum += rand.nextInt(range);
}
System.out.println("Good : " + nf.format(sum/count));

sum = 0;
for (int i=0; i&lt;count; i++) {
sum += Math.abs(rand.nextInt()) % range;
}
System.out.println("Bad : " + nf.format(sum/count));

sum = 0;
for (int i=0; i&lt;count; i++) {
sum += (int)(Math.random() * range);
}
System.out.println("Longer : " + nf.format(sum/count));
}
}

(转载文章请保留出处:北天JAVA技术网(www.java114.com))
 
更多精彩文章:
软考用书
2007年上半年计算机技术与软件专业技术资格(水平)考试 你准备好了吗?
“2007Java技术发展趋势与Java爱好者沙龙成立研讨会”取得圆满成功
反向控制和面向切面编程在Spring的应用
一个java代码自动生产工具
heavenlake"天堂湖"软件自动化生产平台
 
最近评论:
        
你曾悄悄的来过!
wow gold,wow gold,wow gold,ffxi gil max(4926)
        
冰封的往事!
wow power leveling,wow gold,wow power leveling,wow gold max(9262)
        
冰封的往事!
wow power leveling,wow gold,wow power leveling,wow gold max(2994)
        
冰封的往事!
wow power leveling,wow gold,WoW Gold,wow gold max(3472)
        
冰封的往事!
wow power leveling,wow gold,WoW Gold,wow gold max(5509)
        
标 题:   
内 容:   
 
                                  
 
免责声明:该文章由网友发表,如果对您造成侵权,请联系站长

首页 - 承接项目 - 网站地图 - 联系我们 -
版权所有北天JAVA技术工作室 ICP证号:粤ICP备06079815号