【问题标题】:Troubling generating a random order from an ArrayList麻烦从 ArrayList 生成随机顺序
【发布时间】:2017-08-16 12:36:55
【问题描述】:

这里的总新手。我用java编写了一个程序来帮助随机安排我正在组织的音乐会的乐队顺序。我无法让代码正常工作。我得到的输出在打印三个字符串而不是四个字符串后终止,经常重复字符串(我不想要)并在第三个字符串之后终止,并出现以下错误:

"java.lang.IllegalArgumentException: bound 必须是正数"

谁能帮助解决我的代码问题?

public class BandRandomizer
{
public static void main(String[] args) 
{
    ArrayList<String> bands = new ArrayList<>();
    bands.add("Band A");
    bands.add("Band B");
    bands.add("Band C");
    bands.add("Band D");

    Random gen = new Random();
    int index = 0;

    for (int i = 3; i >= 0; i--)
    {
        index = gen.nextInt(i);
        System.out.println(bands.get(index));
        bands.remove(i);    
    }



}

}

【问题讨论】:

  • Collections.shuffle() 怎么样?

标签: java arrays arraylist random


【解决方案1】:

当您调用 nextInt(0) 时,您在最后一个循环中抛出异常:

线程“main”java.lang.IllegalArgumentException 中的异常:绑定必须为正 在 java.util.Random.nextInt(Random.java:388)

应该是:

for (int i = 4; i > 0; i--) { //changed
    index = gen.nextInt(i); // return value in range [0..i) perfect for indexing
    System.out.println(bands.get(index));
    bands.remove(index); //changed
}

您也可以一举removeget remove 返回已删除的项目:

System.out.println(bands.remove(index));

但这是一种不好的洗牌方式,请使用Collections.shuffle

Collections.shuffle(bands);
for (String band : bands) {
    System.out.println(band);
}

【讨论】:

  • 您对索引完全正确,我混淆了 - 然后 i=4 也是如此。谢谢!
【解决方案2】:

您绝对应该使用Collection.shuffle()。但是如果你不想在 JDK 中使用东西,或者你想知道你在哪里做错了,这里就是你的错误。

有两个地方需要修复。

Random.nextInt(x) 返回一个介于 0 和 x - 1 之间的随机整数。因此,您的 i 应该从 4 变为 1:

for (int i = 4; i >= 1; i--)

for 循环的最后一行不正确。我认为您在这里尝试做的是删除已选择的乐队。被选中的波段不在索引i,而是在索引index。因此,将最后一行更改为:

bands.remove(index);

另一种方法是仅从 4 循环到 2 并打印数组列表中的剩余项。我认为这种方法更快。

【讨论】:

  • “另一种方法是只从 4 循环到 2 并打印剩余的项目”但它们肯定仍然是有序的,除非我不明白你的建议。
  • @weston 是的,我可能没有很好地解释这一点。我的意思是保留操作的现有代码,但将 for 循环更改为从 4 循环到 2,因为 nextInt(1) 总是返回 1。
  • 返回 0 但我明白了
【解决方案3】:

试试下面的代码。它适用于您的问题。

public static void main(String[] args) 
{
    ArrayList<String> bands = new ArrayList<>();
    bands.add("Band A");
    bands.add("Band B");
    bands.add("Band C");
    bands.add("Band D");
    int i=1;
    Collections.shuffle(bands);
    for(String band: bands){

        System.out.println(i++ + ". " +band);
    }

}

你得到 Exception 的原因是:nextInt 参数的值必须大于零。

public int nextInt(int n) {
   if (n <= 0)
     throw new IllegalArgumentException("n must be positive");

   if ((n & -n) == n)  // i.e., n is a power of 2
     return (int)((n * (long)next(31)) >> 31);

   int bits, val;
   do {
       bits = next(31);
       val = bits % n;
   } while (bits - val + (n-1) < 0);
   return val;
 }

【讨论】:

  • i++ + ". " + 是怎么回事?
  • 只是为了显示顺序。 i++ 递增值。可以直接使用 System.out.println(band);如果不需要打印序列。
猜你喜欢
  • 1970-01-01
  • 2017-08-23
  • 2012-03-04
  • 1970-01-01
  • 1970-01-01
  • 2011-07-26
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
相关资源
最近更新 更多