我收到了一些代码,我试图通过缩小代码将其设置为更好的格式:
ArrayList<Integer> a = new ArrayList<Integer>();
ArrayList<Integer> c = new ArrayList<Integer>();
for(int i = 0; i < 10; i++) {
int nextInt = rand.nextInt();
while((a.contains(nextInt) ? 1:0) + ((nextInt < 0) ? 1:0) +
((nextInt > 1000) ? 1:0) >= 1){
nextInt = rand.nextInt();
}
a.add(nextInt);
nextInt = rand.nextInt();
while(((c.contains(nextInt))?1:0) + ((nextInt < 0)?1:0) +
((nextInt > 1000)?1:0) >= 1) {
nextInt = rand.nextInt();
}
c.add(nextInt);
}
在while循环中有完全相同的代码,但我想知道如果合并它,随机性是否会丢失。然而,这种情况对我来说似乎很奇怪;有谁能解释一下?你会如何压缩这段代码?
答案 0 :(得分:2)
while条件让我想起了C风格的条件,其中false为0,而true则是0以外的东西。但是,Java有明确的布尔值,因此对条件使用类似的东西更有意义:
a.contains(nextInt) || (nextInt < 0) || (nextInt > 1000)
该代码被放入while
循环中,因为代码显然需要生成0到1000(包括0和1000)的唯一数字列表。如果它违反“ored”的三个条件中的任何一个,那么我们需要生成一个新的随机数并再试一次。如果它违反了第一个条件,则表示该数字不是唯一的,如果它违反了后两个条件中的任何一个,则表示它不在指定的范围内。
我可能会将这个循环放在一个名为generateUniqueValueInrange
的方法或类似的东西中,并将列表和边界作为参数。另外,我猜测rand
是java.util.Random
对象。请注意,Random
有一个nextInt(int n)
方法,可以为您生成一个范围内的数字,这样您就不必继续生成新的数字,直到它们恰好落在您想要的范围内。见http://download.oracle.com/javase/6/docs/api/java/util/Random.html#nextInt%28int%29
另请注意,您正在尝试生成两个包含10个唯一数字的列表,范围从0到1000.因此,您可能会考虑采用更直接的方法来完成此操作。我个人主要使用这里的方法来完成类似的任务,但是“循环直到随机性对我来说”的方法很容易出错,因为如果条件不可能,很容易进入无限循环。
答案 1 :(得分:1)
(a.contains(nextInt) ? 1:0) + ((nextInt < 0) ? 1:0) + ((nextInt > 1000) ? 1:0) >= 1
- &GT; a.contains(nextInt) || nextInt < 0 || nextInt > 1000
答案 2 :(得分:1)
ArrayList<Integer> a = new ArrayList<Integer>();
ArrayList<Integer> c = new ArrayList<Integer>();
public void function(ArrayList<Integer> array){
int nextInt = rand.nextInt();
while((array.contains(nextInt) ? 1:0) || ((nextInt < 0) ? 1:0) ||
((nextInt > 1000) ? 1:0) >= 1){
nextInt = rand.nextInt();
}
array.add(nextInt);
}
for(int i = 0; i < 10; i++) {
function(a);
function(c);
}
不会丢失任何随机性。
答案 3 :(得分:1)
您的while
循环基本上确保随机数在0到1000之间(包括两者),并且之前不存在于列表中。您可以通过调用java.util.Random.nextInt(int n)
方法来优化范围限制。如果您的应用允许您使用Set
代替List
,则您甚至不需要contains
检查。
如果您使用的是List
:
public void addUniqueRandom(List<Integer> list) {
int nextInt;
do {
nextInt = rand.nextInt(1001);
} while(list.contains(nextInt));
list.add(nextInt);
}
ArrayList<Integer> a = new ArrayList<Integer>();
ArrayList<Integer> c = new ArrayList<Integer>();
for(int i = 0; i < 10; i++) {
addUniqueRandom(a);
addUniqueRandom(c);
}
使用Set
s,您需要键入更少的内容:
Set<Integer> a = new HashSet<Integer>();
Set<Integer> c = new HashSet<Integer>();
for(int i = 0; i < 10; i++) {
while (!a.add(rand.nextInt(1001))) // keep trying until we successfully add
;
while (!c.add(rand.nextInt(1001)))
;
}
答案 4 :(得分:1)
看起来您想要两个具有唯一随机数集的列表。这就是我要做的事情:
List<Integer> a = getRandomUniqueList(10, 0, 1000);
List<Integer> b = getRandomUniqueList(10, 0, 1000);
public List<Integer> getRandomUniqueList(int count, int min, int max) {
Random rand = new Random();
Set<Integer> set = new HashSet<Integer>();
for (int i = 0; i < count; i++) {
while (!set.add(min + rand.nextInt(max - min + 1))) {
}
}
return new ArrayList<Integer>(set);
}
Random
类已经有一种限制范围的方法。最初将值放入Set
可以轻松跳过重复项。重用代码对随机性没有影响。如果您使用相同的种子,虽然您将获得不同的随机数,但也没有更改为此方法。如果确实想要更好的随机性,请改用SecureRandom
或Mersenne Twister。
答案 5 :(得分:1)
使用Set(对于没有重复的集合更有意义),您只需要一个循环。
public static Set<Integer> generate(int count, int maxValue) {
Set<Integer> ints = new HashSet<Integer>();
while(ints.size() < count) list.add(rand.nextInt(maxValue+1)));
return ints;
}
Set<Integer> a = generate(10, 1000); // for a set.
List<Integer> c = new ArrayList<Integer>(generate(10, 1000)); // for a list.