2015070102 - EffactiveJava笔记 - 第47条 了解和使用类库(1)
来源:互联网 发布:网络语713是什么意思 编辑:程序博客网 时间:2024/06/08 07:23
20150701 星期三 北京
如果希望产生位于0到某个上届之间的随机整数,如何处理?
privatestatic final Random rnd = new Random();
staticint random (int n) {
returnMath.abs(rnd.nextInt()) % n;
}
存在的错误不容易发觉,可以运行,但是运行的原理导致问题.
1.如果n是比较小的2的乘方,经过比较短的周期,随机数序列会重复;
2.如果n不是2的乘方,某些数会比其他数字出现更加频繁.如果n比较大,缺点更加明显.
可以通过下面的程序体现出来
private static final Random rnd = new Random();
static int random (int n) {
returnMath.abs(rnd.nextInt()) % n;
}
public static void main(String[] args) {
intn = 2 * (Integer.MAX_VALUE / 3);
intlow = 0;
for(int i = 0; i < 1000000; i++) {
if(random(n)< n/2) {
low++;
}
}
System.err.println(low);//666575
}
代码会产生1百万个指定范围的随机数,并打印出来多少数字落在取值范围的前半部分.
预期的结果是打印的数字接近50万,实际结果是666575,由random方法产生的数字2/3落在随机数取值的前半部分.
3.极少情况,结果是灾难性的,返回落在指定范围之外的数字.因为方法调用Math.abs(),将rnd.nextInt()的返回值取绝对值int,如果nextInt()方法返回Integer.MIN_VALUE,那么Math.abs()会返回Integer.MIN_VALUE.确实如此.
System.err.println(Math.abs(Integer.MIN_VALUE));//-2147483648
如果n不是2的次方,那么取模运算返回的是负数,并且很难复现.
System.err.println(Math.abs(Integer.MIN_VALUE) %3); //-2
如何修正这3个问题呢?
有必要了解伪随机数,数论,2的求补运算.但是现有API,Random.nextInt(int)解决问题.
通过使用标准类库,可以充分发挥标准类库专家的知识,以及在你之前其他人的使用经验.
- 2015070102 - EffactiveJava笔记 - 第47条 了解和使用类库(1)
- 2015070103 - EffactiveJava笔记 - 第47条 了解和使用类库(2)
- 2015070507 - EffactiveJava笔记 - 第13条 使类和成员的可访问性最小(1)
- 2015070304 - EffactiveJava笔记 - 第54条 谨慎使用本地方法
- 2015070406 - EffactiveJava笔记 - 第58条 异常使用原则
- 2015070408 - EffactiveJava笔记 - 第60条 优先使用标准异常
- 2015070702 - EffactiveJava笔记 - 第14条 共有类使用访问方法而非共有属性
- 2015070207 - EffactiveJava笔记 - 第50条 尽量避免使用字符串(1)
- 2015070404 - EffactiveJava笔记 - 第57条 只对异常使用异常(1)
- 2015070508 - EffactiveJava笔记 - 第13条 使类和成员的可访问性最小(2)
- 2015070601 - EffactiveJava笔记 - 第13条 使类和成员的可访问性最小(2)
- 2015070701 - EffactiveJava笔记 - 第13条 使类和成员的可访问性最小(3)
- 2015062805 - EffactiveJava笔记 - 第41条 慎用重载(1)
- 2015070704 - EffactiveJava笔记 - 第15条 使可变性最小(1)
- 2015070208 - EffactiveJava笔记 - 第50条 尽量避免使用字符串(2)
- 2015070209 - EffactiveJava笔记 - 第50条 尽量避免使用字符串(3)
- 2015070405 - EffactiveJava笔记 - 第57条 只对异常使用异常(2)
- 2015070407 - EffactiveJava笔记 - 第59条 避免不必要地使用受检异常
- java打包
- 新的开始
- [华为机试练习题]33.二叉搜索树
- shell中使用>/dev/null 2>&1 丢弃信息
- iOS 9: UIStackView入门
- 2015070102 - EffactiveJava笔记 - 第47条 了解和使用类库(1)
- codeforces 557 C
- 黑马程序员---多线程
- TCP/IP详解 卷I 笔记
- JVM调优系列:(一)什么是JVM
- Java基础之简单内存管理
- 排序算法之冒泡排序Java版
- 别不把自己当有钱人 ——让白领族成为百万富翁族的六大理财秘籍
- JVM调优系列:(二)JVM运行时数据区域