如何压缩这段代码?

时间:2011-05-01 17:55:00

标签: java

我收到了一些代码,我试图通过缩小代码将其设置为更好的格式:

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循环中有完全相同的代码,但我想知道如果合并它,随机性是否会丢失。然而,这种情况对我来说似乎很奇怪;有谁能解释一下?你会如何压缩这段代码?

6 个答案:

答案 0 :(得分:2)

while条件让我想起了C风格的条件,其中false为0,而true则是0以外的东西。但是,Java有明确的布尔值,因此对条件使用类似的东西更有意义:

a.contains(nextInt) || (nextInt < 0) || (nextInt > 1000)

该代码被放入while循环中,因为代码显然需要生成0到1000(包括0和1000)的唯一数字列表。如果它违反“ored”的三个条件中的任何一个,那么我们需要生成一个新的随机数并再试一次。如果它违反了第一个条件,则表示该数字不是唯一的,如果它违反了后两个条件中的任何一个,则表示它不在指定的范围内。

我可能会将这个循环放在一个名为generateUniqueValueInrange的方法或类似的东西中,并将列表和边界作为参数。另外,我猜测randjava.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可以轻松跳过重复项。重用代码对随机性没有影响。如果您使用相同的种子,虽然您将获得不同的随机数,但也没有更改为此方法。如果确实想要更好的随机性,请改用SecureRandomMersenne 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.
相关问题