嵌套在终止后循环递增

时间:2014-03-09 15:27:04

标签: java arrays for-loop break off-by-one

我有2个for循环,一个嵌套在另一个循环中。它们遍历2D按钮阵列,以获取使用动作侦听器单击的每个按钮的来源。

找到按钮后,我将按钮的位置/数组索引传递给外部方法。但是,当从按钮数组中找到按钮时,第一个for循环将其终止条件评估为FALSE,但仍然增加i的值。导致一个错误。我的代码在标准动作执行方法中,“event”是ActionEvent。 buttons [] []是一个定义为实例变量的JButton数组。它的尺寸为10 x 10,已添加到面板中。

int i = 0; //this will loop through the columns in the array
int j  = 0; //loop through the rows
boolean locatedSource = false; //allows me to escape both loops

for(i = 0; !(locatedSource) && i < buttons.length; i++) //problem here, when i < buttons.length is FALSE i still gets incremented, leading to an off by one error
{
  for(j = 0; !(locatedSource) && j < buttons.length; j++)
  {
    if(event.getSource() == buttons[i][j])
    {
      locatedSource = true;
      break;
    }
  }
}
//do stuff with i and j in another method. Leads to array out of bounds error / off by one error
}

我应该提到,我不打算用标签来解决这个问题,但似乎不鼓励它们。

4 个答案:

答案 0 :(得分:1)

使用一些布尔标志在内循环中设置它并在外循环的开头检查它。

这是代码:

    boolean found = false;
    for (i = 0; i < 10; i++) // problem here, when i < buttons.length is FALSE i still gets
                             // incremented, leading to an off by one error
    {
        if (found) {
            i--;
            break;
        }
        for (j = 0; j < 5; j++) {
            if (i == 5 && j == 3) {
                found = true;
                break;
            }
        }
        //if (found) {               
        //    break;
        //}
    }

答案 1 :(得分:1)

三种可能的解决方案:

  1. 明确设置“找到”索引,不要重复使用for循环索引。
  2. 使用自己的方法进行搜索,并直接从循环中return进行搜索。
  3. 完成循环后将i减1。

答案 2 :(得分:1)

你的代码包含注释“这里的问题,当我&lt; buttons.length为FALSE时,我仍然会增加,导致一个错误”,这在事件的排序中是错误的。

首先执行循环更新块(如i++),然后检查条件(如`i&lt; buttons.length')。

意思是,i == buttons.length是循环结束后没有触发locatedSource条件的正确状态。

答案 3 :(得分:1)

问题说明

for循环的增量表达式在之后执行,而不是之前的每次循环迭代。请参阅Oracle Java tutorial

中的以下引用

for语句提供了一种迭代一系列值的简洁方法。程序员经常将其称为“for循环”,因为它反复循环直到满足特定条件的方式。 for语句的一般形式可表示如下:

for (initialization; termination;
     increment) {
    statement(s)
}

使用此版本的for语句时,请记住:

  1. 初始化表达式初始化循环;当循环开始时,它被执行一次。
  2. 当终止表达式的计算结果为false时,循环终止。
  3. 每次迭代循环后调用increment表达式;这个表达式增加或减少一个值是完全可以接受的。
  4. For循环解决方案

    您可以重新编写循环,以便增量是循环内的第一个语句。

        for (i = 0; !(locatedSource) && i < buttons.length;) {
            i++;
            for (j = 0; !(locatedSource) && j < buttons.length;) {
                j++;
                if (event.getSource() == buttons[i][j]) {
                    locatedSource = true;
                }
            }
        }
    

    While Loop Version

    鉴于循环变量都是在循环之外初始化而你不想使用for循环增量表达式,重写代码以使用while循环可能更清楚,如下所示:

        while (!(locatedSource) && i < buttons.length) {
            i++;
            while (!(locatedSource) && j < buttons.length) {
                j++;
                if (event.getSource() == buttons[i][j]) {
                    locatedSource = true;
                }
            }
        }