• 找课程
  • 找学校
  • 找资料
  • 成才首页
  • 高考
  • 外语
  • 考研
  • 公务员
  • 计算机/IT
  • 职业培训
  • 基础教育
  • 司法考试
  • 出国留学
  • 管理学院
  • 文体艺术
  • 课程
  • 学校
  • 资料
  • 社区
当前位置:成才网 > 新闻中心 > 计算机/IT > > 正文
JAVA中实现随机整数的生成
2007-05-21 13:45:50  来源:考试大      标签:艺考辅导 
  使用Java 2 SDK基础类库产生随机数的方法很多。但是如果你跟不上这些类库的更新脚步,你有可能正在使用的是一种低效的随机数生成机制,更糟糕的是:你有可能得到的不是均匀分布的随机数。本文将向你展示一种较为可靠的随机数生成方法,同时与其他方法进行比较。 

  自从JDK最初版本发布起,我们就可以使用java.util.Random类产生随机数了。在JDK1.2中,Random类有了一个名为nextInt()的方法: 
public int nextInt(int n) 
给定一个参数n,nextInt(n)将返回一个大于等于0小于n的随机数,即:0 <= nextInt(n) < 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<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<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<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<count; i++) { 
sum += rand.nextInt(range); 
} 
System.out.println("Good : " + nf.format(sum/count)); 

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

sum = 0; 
for (int i=0; i<count; i++) { 
sum += (int)(Math.random() * range); 
} 
System.out.println("Longer : " + nf.format(sum/count)); 
} 
} 
上一篇:关于Cisco认证考试的注意事项
下一篇:Java技术与XML常见问题之JAX-RPC
   (已有0人评论)
相关新闻
-  桓文教育CCNA、CCNP开班情况火爆,学员好评如潮
-  谷歌与流氓软件为伍不是出路
-  微软陈永正肯定北京奥运会要用Vista系统
-  资深IT教育专家提醒您:慎选IT培训机构
-  网络招聘需提防虚假信息
-  IT人才需求量继续猛增
学习资料免费下载
  • -  [日语] 将軍と大名   立即下载
  • -  [自考] 全国2008年1月高等教育自学考试法律文书写作   立即下载
  • -  [自考] 08自考“政治经济学(财)”知识点(二)   立即下载
  • -  [西班牙语] 西班牙语常用动词的基本用法(二)    立即下载
  • -  [西班牙语] 与美女搭讪西班牙语12句    立即下载
  • -  [日语] 标准日本语句型7   立即下载
  • -  [日语] 学习日语中的客套话    立即下载
  • -  [市场营销] 解析“招商”的三重境界    立即下载
  • -  [市场营销] 成为优秀业务员必经的三个发展阶段    立即下载
  • -  [市场营销] 营销练得是细功夫    立即下载
  • 进入下载更多更全的资料>>
  • 有更好的资料但是不想共享?可以开店售卖你的资料,把它变成真正的财富!
学习吧社区 • 论坛 • 博客 • 圈子
-  [司法考试] 2008年国家司法考试【新法】必看 东界
-  [公务员考试] 经验分享:我的国家公务员考试全程经验 ftisland
-  [司法考试] 2008年司法考试:构建你整体的复习思路 钢笔
-  [公务员考试] 公务员考试经验谈:我和我的梦擦肩而过 和田
-  [司法考试] 2008年司法考试备考:心态决定成败 钢笔
-  [公务员考试] 考试经验交流:公务员考试复习实战三招 东界
  • 司法考试商经考点之用人单位...

  • 陈若琳摘金"童言无忌" "什么好吃吃什么"...

  • 公务员考试心得:在明媚的春光里舞蹈...

  • 奥运会最牛女裁判:17岁周丽娜走红网络...

  • “少年发明家”高考得266分 被高校破格录取...

成才网温馨提示

  • 由于学校开课信息变动较快,未能及时变更信息。为了保证您的正常学习,请您在报名前拨打页面中的免费咨询电话了解详情后进行报名。
  • 更多问题请咨询客服中心:
  • 4006504560-789000(手机固话均可拨打)
  • 服务时间:周一至周日 早9:00-18:00
  • >>立即免费注册教誉通,免费发布学校信息及课程信息,让更多学员找到您!

最新课程

  • •
  • 2009届艺术类高复班招生 09月08日
  • •
  • 2010届、2011届三校生高考辅导班 09月01日
  • •
  • 2009届三校生高复班招生简章 09月01日
  • •
  • 高级营销员资格培训 08月15日
  • •
  • 营销员资格培训 08月15日
  • •
  • 助理营销师资格培训 08月15日
  • •
  • 营销师资格培训 08月15日
  • •
  • 清华大学《现代企业资本战略》董... 09月22日

更多优惠

  • •
  • 摄影师职业培训  学费1200  成才价1104  省 96元
  • •
  • 美德创意广告英语培训  学费1650  成才价1550  省 100元
  • •
  • 信息化营销师  学费1996  成才价786  省 1210元
  • •
  • 中科院软件需求分析和管理短训班  学费3600  成才价3240  省 360元
  • •
  • 中科院高级软件测试课程短训班  学费3800  成才价0  省 3800元
  • •
  • 软件项目管理实践  学费3300  成才价0  省 3300元
  • •
  • 游戏学院游戏美术设计  学费16800  成才价16800  省 0元
  • •
  • 游戏学院游戏程序开发  学费16800  成才价16800  省 0元
  • •
  • 北大青鸟网络工程师培训  学费4675  成才价4488  省 187元
  • •
  • 英华新概念英语二册课程  学费1290  成才价1290  省 0元
  • •
  • 英华新概念英语(三册)课程  学费1100  成才价1056  省 44元
  • •
  • VS.NET企业级开发培训课程  学费5580  成才价0  省 5580元

推荐教育机构

最受关注的学校

  • •  北京第二外国语学院旅游发展研究院
  • •  上海复旦托业教育培训中心
  • •  中建院培训中心
  • •  北京成功时代培训中心
  • •  北京邦杰外语学校(成教中心)
  • •  北京易中创业科技有限公司
  • •  Englishing 英格利教育
  • •  清华继续教育学院
  • •  北大青鸟丰台学知堂
  • •  杭州里仁教育咨询有限公司