2015-10-11 61 views
2

我正在尝试编写模拟拼字游戏的代码。我设计了一个应该模拟拼字游戏包的类,我试图在选择一个随机拼图后,通过在main中打印tileID来测试它。每当我虽然运行的代码,我不断收到以下错误:为什么我收到“必须是正面的”错误?

Exception in thread "main" java.lang.IllegalArgumentException: bound must be positive at java.util.Random.nextInt(Random.java:388) at hw3.RandomBag.randomPick(RandomBag.java:39) at hw3.RandomBag.main(RandomBag.java:59

有人可以告诉我为什么我收到这个错误?

import java.util.*; 

public class RandomBag<E> implements Iterable<E> { 

    // instance varibles 
    private List<E> bag; // arraylist as the container 
    private Random rand; // random number generator 

    // constructors 
    public RandomBag() { 
     bag = new ArrayList<E>(); 
     rand = new Random();  
    } 

    public RandomBag(int seed) { 
     bag = new ArrayList<E>(); 
     rand = new Random(seed); 

    } 

    // returns the size of the bag 
    public int size() { return this.bag.size(); } 

    public boolean isEmpty() { // returns true/false if the bag is/is not empty 
     if (this.bag.isEmpty()) 
      return true; 
     else 
      return false; 
    } 

    // adds the parameter element in the bag 
    public void add (E element) {this.bag.add(element);} 

    // randomly selects an element using the random number generator 'rand' and removes that element from the bag, and returns the element 
    public E randomPick() { 

     int index = rand.nextInt(this.bag.size()); 
     E tileID = bag.remove(index); 
     return tileID; 
    } 

    // obtains an iterator for the bag, and returns it 
    public Iterator<E> iterator() { 
     // traverse bag using an iterator 
     Iterator it = bag.iterator(); 
     return it; 
    } 

     //** 
     //** main() for testing RandomBag<E> 
     //** 
    public static void main(String[] args) { 

     RandomBag bag = new RandomBag(); 

     Object tileID = bag.randomPick(); 
     System.out.println(tileID); 

    } 
} 

回答

8

如果this.bag.size()为0,则传递了无效的参数nextInt()

这在Javadoc明确规定:

n the bound on the random number to be returned. Must be positive.

nextInt(n)返回0和n-1之间的数。你认为nextInt(0)返回什么?

在你的主要方法中,你试图挑选一个空袋子的元素。它不能工作。在致电randomPick()之前,您应该检查包的大小。当袋子空了时,randomPick()应该会抛出异常。

public static void main(String[] args) { 

    RandomBag bag = new RandomBag(); 

    Object tileID = null; 
    if (bag.size() > 0) 
     tileID = bag.randomPick(); 
    System.out.println(tileID); 

} 
+0

我感到困惑,因为即使我选择的任意数,并把它在的地方this.bag.size的' ()',我仍然得到错误:'在线程中的异常“主”java.lang.IndexOutOfBoundsException:索引:0,大小:0 \t在java.util.ArrayList.rangeCheck(ArrayList.java:653) \t at在hw3.RandomBag.main(java.util.ArrayList.remove(ArrayList.java:492) \t Bag.java:59) ' –

+0

虽然正确,但我会争辩说Javadoc不够明确。零是一个正数吗?它没有用连字符作为前缀,所以有些人可能会说是。在其他情况下,有0的显式正面和负面版本。文档可能会更好地声明“必须是正数,大于0”。 – adelphus

+0

@OmarN这是一个完全不同的错误。如果你的列表为空,试图为任何索引调用'remove'将导致'IndexOutOfBoundsException'。在调用'randomPick'之前,你应该确保你的List不是空的。这样你的原始代码就可以工作。 – Eran

1

错误说明了一切:

Exception in thread "main" java.lang.IllegalArgumentException: bound must be positive 
    at java.util.Random.nextInt(Random.java:388) 

每当必然是zeronegative,它是一个非法参数rand.nextInt()。确保this.bag.size()从不zero

+0

这是有道理的,但是即使我把一个任意数字代替'this.bag.size()',我也会感到困惑:在线程“main”中的异常java.lang.IndexOutOfBoundsException:索引:0,大小:0 \t at java.util.ArrayList.rangeCheck(ArrayList.java:653) \t at java.util.ArrayList.remove(ArrayList。 java:492) \t at hw3.RandomBag.randomPick(RandomBag.java:40) \t at hw3.RandomBag.main(RandomBag.java:59) ' –

1

该错误是因为线62在类的情况发生:

int index = rand.nextInt(this.bag.size()); 

如果空着袋子调用此代码,它将始终返回0

下一个步骤是检查

if (bound <= 0) 
     throw new IllegalArgumentException(BadBound); 

由于我们:线387类java.util.Random总是从this.bag.size()得到0,它总是会抛出异常。

要让它工作,确保元素添加到包,如:

public static void main(String[] args) { 

    RandomBag bag = new RandomBag(); 

    for (int i = 0; i < 10; i++) { 
     bag.add(i); // adding elements 
    } 

    Object tileID = bag.randomPick(); 

    System.out.println(tileID); 

} 
相关问题