带有随机种子的Java树映射没有固定的大小
我想用它生成10个Udisk实例,价格和容量都是随机的
// test.java
import java.util.*;
class Udisk {
float price;
int capacity;
Udisk(float p, int c) {
this.price = p;
this.capacity = c;
}
@Override
public String toString() {
return "Udisk price: "+this.price+" capacity: "+this.capacity;
}
}
class Main {
public static void main(String[] args) {
Map<Float, Udisk> tm = new TreeMap<Float, Udisk>();
for(int count=0; count < 10; count++) {
Random rand = new Random(System.currentTimeMillis());
float price = Math.abs(rand.nextInt())%100;
int capacity = Math.abs(rand.nextInt())%10;
Udisk u = new Udisk(price, capacity);
tm.put(u.price, u);
}
System.out.println(tm+ " "+tm.size());
}
}
在javac test.java
之后,我运行了几次java Main
,结果非常奇怪
First Time: {3.0=Udisk price: 3.0 capacity: 1} 1
Second Time: {33.0=Udisk price: 33.0 capacity: 8, 86.0=Udisk price: 86.0 capacity: 0} 2
Third Time: {46.0=Udisk price: 46.0 capacity: 8} 1
Fourth Time: {24.0=Udisk price: 24.0 capacity: 1, 73.0=Udisk price: 73.0 capacity: 5} 2
所有这些结果在树状图中只有不到10项。将代码更改为
import java.util.*;
class Udisk {
float price;
int capacity;
Udisk(float p, int c) {
this.price = p;
this.capacity = c;
}
@Override
public String toString() {
return "Udisk price: "+this.price+" capacity: "+this.capacity;
}
}
class Main {
public static void main(String[] args) {
Map<Float, Udisk> tm = new TreeMap<Float, Udisk>();
for(int count=0; count < 10; count++) {
Random rand = new Random(System.currentTimeMillis());
float price = Math.abs(count)%100;
int capacity = Math.abs(count)%10;
Udisk u = new Udisk(price, capacity);
tm.put(u.price, u);
}
System.out.println(tm+ " "+tm.size());
}
}
答案是正确的
{0.0=Udisk price: 0.0 capacity: 0, 1.0=Udisk price: 1.0 capacity: 1,
2.0=Udisk price: 2.0 capacity: 2, 3.0=Udisk price: 3.0 capacity: 3,
4.0=Udisk price: 4.0 capacity: 4, 5.0=Udisk price: 5.0 capacity: 5,
6.0=Udisk price: 6.0 capacity: 6, 7.0=Udisk price: 7.0 capacity: 7,
8.0=Udisk price: 8.0 capacity: 8, 9.0=Udisk price: 9.0 capacity: 9} 10
我想知道我在随机中错过了什么导致了前一个问题,谢谢你的帮助
# 1 楼答案
对此有一些想法:
a)在循环中初始化随机数的代价很高——你总是初始化一个新的随机伪随机数序列,而你也可以把随机创建从循环中拉出来完成
b)贵方价格为整数模100->;只有100个可能的值,因此可能会出现键冲突(在这种情况下,10次迭代不会创建10个不同的元素)
最重要的是
c)
System.currentTimeMillis()
可能太慢了。你的循环只会创建一个对象并将其放入地图中——这非常、非常快(即使使用随机种子)。 这可能是由于System.currentTimeMillis()
在迭代之间没有改变(请参见a),所以您只需使用相同的种子值来初始化伪随机序列。同一种子的随机数产生相同的序列。因此,除非你的System.currentTimeMillis()
在迭代之间发生变化(在某些系统上,这种变化只会每15毫秒发生一次),否则你最终只能得到一个或最多两个不同的价格值尝试将随机数从循环中拉出:
现在你应该接近10个值。然而,你可能会运气不好,画两次相同的
nextInt()
值——因此,如果你需要正好10个值,我建议让循环条件:祝你好运