for循环中ArrayList的奇怪错误

时间:2014-02-28 21:00:42

标签: java arraylist switch-statement

我有一个非常奇怪的问题,问题只出现在案例3& 4。

                for(Sector sector : sectoren)
    {
        switch(sector.getCode())
        {
            case 1:
                for(int i = 0; i<3; i++)
                {
                    for(int j=0;j<3; j++)
                    {
                        Gebiedskaart gbk = gebiedskaarten.get(r.nextInt(gebiedskaarten.size()));
                        vakken[i][j].setGbk(gbk);
                        gebiedskaarten.remove(gbk);
                    }
                vakken[2][2].setGbk(null);
                }
            case 2:
                for(int i = 0; i<3; i++)
                {
                    for(int j=4;j<7; j++)
                    {
                        Gebiedskaart gbk = gebiedskaarten.get(r.nextInt(gebiedskaarten.size()));
                        vakken[i][j].setGbk(gbk);
                        gebiedskaarten.remove(gbk);
                    }
                }
                vakken[2][4].setGbk(null);
            case 3:
                for(int i=4; i<7; i++)
                {
                    for(int j=0;j<3; j++)
                    {
                        System.out.println(gebiedskaarten.size());
                        Gebiedskaart gbk = gebiedskaarten.get(r.nextInt(gebiedskaarten.size()));
                        vakken[i][j].setGbk(gbk);
                        gebiedskaarten.remove(gbk);
                    }
                }
                vakken[4][2].setGbk(null);
           case 4:
                for(int i = 4; i<7; i++)
                {
                    for(int j=4;j<7; j++)
                    {
                        Gebiedskaart gbk = gebiedskaarten.get(r.nextInt(gebiedskaarten.size()));
                        vakken[i][j].setGbk(gbk);
                        //gebiedskaarten.remove(gbk); doet iets raar? moeten we nog naar kijken, hij blijft gewoon verwijderen tot de lijst leeg is
                    }
                }
                vakken[4][4].setGbk(null);
        }
    }

在代码中你可以看到我为数组赋值,然后我从ArrayList中删除了该值。你可以看到我把System.out.println放在那里,看看它做了什么,这就是输出:

34
33
32
31
30
29
28
27
26
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0

然后显然是错误:

Exception in thread "main" java.lang.IllegalArgumentException: n must be positive
    at java.util.Random.nextInt(Random.java:300)
    at domein.Spelbord.wijsGebiedskaartenToe(Spelbord.java:123)
    at domein.Spelbord.<init>(Spelbord.java:19)
    at domein.Spel.setWereldkaart(Spel.java:18)
    at domein.DomeinController.maakWereldkaart(DomeinController.java:39)
    at ui.Uc1.maakWereldkaart(Uc1.java:42)
    at ui.ConsoleApplicatie.behandelUc1(ConsoleApplicatie.java:67)
    at ui.ConsoleApplicatie.startSpel(ConsoleApplicatie.java:29)
    at StartUp.main(StartUp.java:12)
Java Result: 1

我对最新情况一无所知,也许你们有吗?

3 个答案:

答案 0 :(得分:4)

这是因为你这样做:

 r.nextInt(gebiedskaarten.size());

gebiedskaarten.size() == 0

==&GT;你试着从0到0得到一个随机数==&gt;例外

更新:看起来您忘记了交换机案例中的break;语句!我想你想成为你的代码逻辑:

 switch(sector.getCode()) {
 case 1: /*do something*/ break;
 case 2: /*do something else */ break;
 //...
 default: //do some default action
 }

另见相关问题:Why do we need break after case statements?

答案 1 :(得分:2)

您正在使用值0调用Random.nextInt(),但不支持。

System.out的输出中可以看出,数组最终的大小为0,并且您将数组的大小传递给nextInt()

另见http://docs.oracle.com/javase/7/docs/api/java/util/Random.html#nextInt(int)

答案 2 :(得分:1)

我不知道为什么你的循环运行这么多次,而预计只有9(3 * 3)次,但假设你发布的代码是在gebiedskaarten.size() == 9时开始的,它会执行以下9次迭代:

  • System.out.println(gebiedskaarten.size())
    • 打印当前尺寸。
  • Gebiedskaart gbk = gebiedskaarten.get(r.nextInt(gebiedskaarten.size()))
    • 首先使用r.nextInt(...)执行gebiedskaarten.size(),获取新的随机值。
    • 然后使用该随机数调用gebiedskaarten.get(...)并将其分配给gbk
  • vakken[i][j].setGbk(gbk);
    • setGbk(gbk)的{​​{1}}条目上拨打i, j
  • vakken
    • gebiedskaarten.remove(gbk);集合中移除gbk,将尺寸减小一个。

哪里出错,是某个点,gebiedskaarten变为gebiedskaarten.size(),并且您尝试通过0上的r.nextInt(...)获取新的随机数,而不是0可能,因为它需要严格正面。
但请注意,调用gebiedskaarten.get(0)是有效的,因此您有一次性错误。

我还强烈建议您从荷兰语命名惯例转到英语命名惯例,因为它可以帮助您在职业生涯的未来和在线发布问题。

另外,为了完整性,正如@donfuxx指出的那样,你的switch语句不符合标准,这导致99%的时间出错,应该是这样:

switch (variable) {
    case 1:
        //do interesting things
        break;
    case 2:
        //do interesting things
        break;
    case 3:
        //do interesting things
        break;
    default:
        //either allowable base case, or may-not-happen error case
        break;

如您所见,我在每个break的末尾添加了case,这是防止它落入语句所必需的。如果break末尾没有case 1,则case 2执行。