简体   繁体   English

for循环中带有ArrayList的奇怪错误

[英]Weird error with an ArrayList in for-loop

I have a very weird problem, the problem only presents itself in case 3 & 4. 我有一个很奇怪的问题,问题只在情况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);
        }
    }

in the code you can see that I assign a value to an array, and then i remove that value from the ArrayList. 在代码中,您可以看到我为数组分配了一个值,然后从ArrayList中删除了该值。 You can see I have put the System.out.println there, to see what it does, and this is the output: 您可以看到我将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

And then the error obviously: 然后错误显然是:

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

I don't have a clue of whats going on, maybe you guys have? 我不知道发生了什么事,也许你们有吗?

It is because you do: 这是因为您这样做:

 r.nextInt(gebiedskaarten.size());

when gebiedskaarten.size() == 0 gebiedskaarten.size() == 0

==> you try get a random number from 0 to 0 ==> Exception ==>您尝试获取0到0之间的随机数==>异常

Update: it also looks like you forgot the break; 更新:看起来您也忘记了break; statements in your switch-case! 您的开关盒中的声明! I guess you want to be your code logic to be like that: 我想你想成为你的代码逻辑是这样的:

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

see also related question: Why do we need break after case statements? 另请参阅相关问题: 为什么我们需要在事后陈述中休息?

You are calling Random.nextInt() with a value of 0, which is not supported. 您正在调用Random.nextInt()的值为0,这是不受支持的。

As you see from the output of System.out , the array finally has a size of 0, and you are passing the array's size to nextInt() . System.out的输出中可以看到,该数组的大小最终为0,并将该数组的大小传递给nextInt()

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

I do not know why your loop runs so many times, while only 9 (3 * 3) times is expected, but assuming that the code you posted starts when gebiedskaarten.size() == 9 , it does the follow for 9 iterations: 我不知道为什么循环会运行这么多次,而预期只有9(3 * 3)次,但是假设您发布的代码在gebiedskaarten.size() == 9时开始,它将执行9次迭代:

  • System.out.println(gebiedskaarten.size())
    • Prints the current size. 打印当前尺寸。
  • Gebiedskaart gbk = gebiedskaarten.get(r.nextInt(gebiedskaarten.size()))
    • First executes r.nextInt(...) with gebiedskaarten.size() , obtaining a new random value. 首先使用gebiedskaarten.size()执行r.nextInt(...) ,获得一个新的随机值。
    • Then calls gebiedskaarten.get(...) with that random number and assigns it to gbk . 然后使用该随机数调用gebiedskaarten.get(...) ,并将其分配给gbk
  • vakken[i][j].setGbk(gbk);
    • Calls setGbk(gbk) on the i, j entry of vakken . 调用setGbk(gbk)i, j进入vakken
  • gebiedskaarten.remove(gbk);
    • Removes gbk from the gebiedskaarten collection, reducing the size by one. gebiedskaarten集合中删除gbk ,将大小减小gebiedskaarten

Where it goes wrong, is that a certain point, gebiedskaarten.size() becomes 0 , and you try to obtain a new random via r.nextInt(...) on 0 , which is not possible, as it needs to be strictly positive. 哪里出错了,是某个点gebiedskaarten.size()变为0 ,而您尝试通过r.nextInt(...)0上获得一个新的随机r.nextInt(...) ,这是不可能的,因为它必须严格正。
Note however that calling gebiedskaarten.get(0) is valid, so you have an one-off error. 但是请注意,调用gebiedskaarten.get(0)是有效的,因此会出现一次性错误。

I also strongly suggest you to move from Dutch naming conventions to English naming conventions, as it will help you a lot in either your career future and in posting questions online. 我也强烈建议您从荷兰命名约定转为英语命名约定,因为这将对您的职业生涯和在线发布问题有很大帮助。

Also, for completeness' sake, as @donfuxx has pointed out, your switch statements are not conform standards, which lead to errors in 99% of the time, it should be such: 同样,出于完整性的考虑,正如@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;

As you see I have added a break at the end of every case , this is neccessary to prevent it from falling through the statements. 如您所见,我在每种case的末尾都添加了一个break点,这是必要的,以防止它落入语句中。 If there is no break at the end of case 1 , then case 2 will also get executed. 如果case 1结束时没有break ,则case 2 将执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM