读书笔记effective java 之通用程序设计2

本文讨论了在Java中生成随机数的一种常见但不理想的方法及其存在的问题,并介绍了如何利用类库来避免这些问题。此外,文章还强调了在需要精确结果的情况下,避免使用float和double类型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第三条 了解和使用类库

假如我们想产生位于0到某个数之间的随机整数,一般会像这样做
private static final Random rd=new Random();
static int random(int n){
return Math.abs(rd.nextInt())%n;
}

这个方法看起来不错,但是却有三个缺点。第一个缺点是,如果n是一个比较小的2的乘方

,经过一段相当短的周期后,它产生的随机数序列将会重复。第二个缺点是,如果n不是2的乘

方,那么平均起来,有些数会比其他数出现的更为频繁。如果n比较大,这个缺点会非常明显

。这个可以通过下面的程序直观地体现出来,
  
public static vodi main(String []args){
int n=2*(Integer.MAX_VALUE/3);
int low=0;
for(int i=0;i<1000000;i++){
if(random(n)<n/2)
low++;
System.out.println(low);
}
}

如果random方法工作正常的话,这个程序打印出来的数将接近一百万的一半,但是如果真正
运行这个程序,就会发现它打印出来的数字接近于66666,由random方法产生的数字有2/3落在

随机数取值范围的前半部分。 radom 方法的第三个缺点是,在极少数情况下,它的失败是灾难性的,返回一个落在指定范围之外的数。之所以如此,是因为这个方法试图通过调用Math.abs(),将rnd.nextInt()返回的值映射为一个非负整数int,如果nextInt()返回Integer.MIN_VALUE,那么Math.abs也会返回Integer.MIN_VALUE,假设n不是2的乘方,那么取摸操作符(%)将返回一个负数.这几乎肯定会
使程序失败,而且这种失败很难重现。

使用类库可以充分利用这些编写标准库的专家知识,以及在你之前的其他人的经验。可以不必浪费时间为那些与工作不太相关的问提供特别的解决方案。最后类库的性能将会随着时间推移性能将不断提高。



第四条 如果需要精确的答案,请避免使用float 和double

float 和double 类型主要是为了科学计算和工程计算而设计的,它们执行二级制浮点运算,这是为了在广泛的数值范围上提供较为精确的快速近似计算而精心设计的。然而,它们并没有提供完全的精确的结果,所以不应该被用于需要精确结果的场合,float和double类型尤其不适合货币计算。
例如,假如你的口袋有$1.03,花掉了42$之后还剩下多少钱,
System.out.println(1.03-.42);

结果是0.6100000000000001
解决这个问题需要用BigDecimal,int,long进行货币计算
注:以上摘自《effective java 中文版》
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值