【问题标题】:Dont understand for each loop with two dimensional array不了解每个带有二维数组的循环
【发布时间】:2014-03-05 23:49:16
【问题描述】:

从我的书中得到这个例子:

public class ForEach3 {
public static void main(String args[]){
    int sum=0;
    int numbers [][]=new int[3][5];

    for(int i=0;i<3;i++)
    {
        for(int j=0;j<5;j++)
        {
            numbers[i][j]=(i+1)*(j+1);
        }
    }


    for(int x[]:numbers)
    {
        for(int y:x)
        {
            System.out.println("Number is: "+y);
            sum+=y;
        }
    }
}
}

在谈到这个循环之前,我什么都懂:

or(int x[]:numbers)
    {
        for(int y:x)

为什么我们必须做这个循环? : for(int y:x) 那是让我很困惑的部分,我知道如何使用基本数组为每个循环做基本操作,但是当我使用二维数组时这让我很困惑..

【问题讨论】:

  • for(int[] x : numbers) 的不常见语法如果这有助于您理解
  • 还是不明白,抱歉..

标签: java arrays foreach


【解决方案1】:

好的,请考虑以下代码:

for(int x[] : numbers) {
    for(int y : x) {
        System.out.println("Number is: " + y);
    }
}

现在,在第一行,您会看到一些奇怪的语法。 int x[]int[] x 说的一样。 (就是说同一件事的不同方式。)基本上,您是在声明一个数组。现在foreach 循环将您在:numbers 之后指定的数组中的每个元素放入您在:x 之前声明的变量中。

现在,了解此代码的最佳方法是了解二维数组的工作原理。它们不是什么新的特别的东西,所有的二维数组都是一个数组数组。与传统数组中的每个元素都不是一个值不同,每个元素都是一个完整的另一个数组,具有自己的一组值。那么让我们再看一遍最上面的代码行。

for(int x[] : numbers) {

这在英语中翻译为“对于numbers 中的每个元素,将其值放入x 并运行以下代码。”请记住,因为numbers 是一个数组数组,所以它的每个元素都是一个数组。因此代码运行第一次迭代,并检索numbers 中的第一个元素(在索引0 处),它是ints 的数组。然后,它运行以下代码:

for(int y : x) {
    System.out.println("Number is: " + y);
}

第一行代码可以翻译成英文如下:“对于x 中的每个元素,将其值放入y 并运行下面的代码。”所以,它就是这样做的。代码运行第一次迭代并检索x 中的第一个元素,即int。然后,它运行代码:

System.out.println("Number is: " + y);

当然,这会打印出它检索到的值。然后,内部for 循环继续遍历数组x,直到到达末尾。此时,就像任何其他 for 循环一样,它会退出。

现在,请记住,您仍处于 for(int x[] : numbers) 循环的第一次迭代中。所以现在里面的所有代码都已经运行了,它检索numbers 中的下一个元素,或下一个数组。 (因为numbers 是一个数组数组)它再次运行下面的代码,重复直到它运行numbers 中每个元素(或数组)的代码。

希望对您有所帮助。欢迎在 cmets 中向我提问。

编辑:

对于您在 cmets 中的问题,让我们以图形方式查看。

所以这里的橙色框是numbers。它是一个数组。它的每一个元素都在一个蓝色框中。 (共 3 个)。现在,看看顶部的蓝色框。它是一个数组。顶部的蓝色框是numbers[0],或者,(在外循环的第一次迭代期间)x。现在看看顶部蓝色盒子的内部,绿色盒子。蓝色框的每个元素都由一个绿色框表示。每个绿色框是一个int。第一个蓝色框中的第一个绿色框是(在外循环的第一次迭代期间)x[0],或(在外循环和内循环的第一次迭代期间)y。所以外循环遍历橙色框(numbers)中的所有蓝色框(x),内循环遍历蓝色框(@987654358)中的所有绿色框(y) @) 它被赋予了。

这样更有意义吗?

【讨论】:

  • 是的,完全理解,但是。我想知道为什么这第一个 for(int y:x) 不能运行这个 println?为什么它必须将他的值传递给变量 y ?因为它们具有相同的值。正如您所说:“对于 x 中的每个元素,将其值放在 y 中并运行下面的代码。这是我不明白为什么必须将值传递给 y 的部分?跨度>
  • 因为x 是一个整数数组。您需要遍历x 的每个值。在这种情况下,您将y 设置为等于每个值。这与将x 设置为等于int[][] 调用数字中的每个int[] 相同。
  • @miljannet 有关详细信息,请查看我对图形的编辑。
  • 谢谢安德鲁!现在知道了,非常感谢你们。
【解决方案2】:

首先,我们要将numbers 重命名为grid,将x 重命名为row,并将y 重命名为cell。让我们分解一下。

for (int x[]:numbers) 可以重写为for (int[] row : grid)。这将遍历存储在grid 中的所有int[]s。对于每个int[]row 设置为那个int[]

内部循环 for (int y : x) 重写为 for (int cell : row) 正在迭代 row 的所有值,这是一个 int[],并将 cell 设置为等于每个值。第一次运行外部然后内部循环时,row 等于 grid[0] 并且 cell 等于 row[0]grid[0][0]。这种情况一直持续到grid 中的每个值都被使用为止。

【讨论】:

  • 现在明白为什么最好使用 int[] x,但仍然不明白这个 for(int y:x) 循环在做什么?我知道 x 从数组 numbers 继承了数字。但是为什么这个 int y 需要从变量 x 继承数字? y 每次都和 x 一样?
【解决方案3】:

二维数组实际上是(一维)数组的数组。 int[][] 中的每一行或每一列(取决于您对二维数组的看法)都是一个 int[],其中的每个项目都是一个简单的 int

使用一些(希望)不那么容易混淆的名称,你的代码就变成了

int[][] grid = new int[5][5];

for (int[] row : grid)
{
    for(int cell : row)
    {
        System.out.println(cell);
    }
}

因此,外部循环遍历行,而内部循环遍历这些行内的元素(每次都是不同的行),直到循环访问网格中的每个单元格一次。

【讨论】:

  • 变量的重命名很有帮助。
【解决方案4】:

第一个循环描述了第一个数组 (length == 3) 的索引,其中又有length == 5 的数组。第二个循环是遍历您的 numbers 数组并在新行中打印出每个值。

所以它从[0][0...4][1][0...4] 和最后一个[2][0...4] 并打印出每个值。

【讨论】:

  • 循环的较短版本,称为增强的 for 循环,允许在不维护计数器变量的情况下对数组或集合进行迭代。它被称为语法糖;这是做某事的更快方法。适合自己;)
  • 实际上,我确实喜欢增强的 for 循环,因为它更不容易出错(整体代码更少)并且更易于阅读。
  • @nrubin29 大家好,当我猜测增强的 for 循环只能增加 +1 时,我错了吗?或者当增加 +3 时它看起来像这样:for(int cell : row+3) {} Thx!
  • rowint[],因此您不能将 3 添加到 row。如果你想遍历每三个元素,你会使用标准的 for 循环,将计数器增加 3。
【解决方案5】:
for(int x[]:numbers)

这里你迭代numbers[0],numbers[1],numbers[2],numbers[i]的值被放入变量x。那么 x 是一个你在其中迭代的一维数组:

for(int y:x)

【讨论】:

    【解决方案6】:

    这是关键点:实际上没有“二维数组”这样的东西。正如int[]int 的数组一样,int[][]int[] 的数组。当您说myArray[1][2] 时,它并没有真正进入网格的坐标 (1, 2)。 myArray 是一个数组数组,所以myArray[1] 给你一个数组,它由[2] 索引。

    或者,重写示例的第一部分:

    int numbers[][] = new int[3][5];
    for(int i = 0; i < 3; i++)
    {
        int[] array = numbers[i];
        for(int j=0;j<5;j++)
        {
            array[j]=(i+1)*(j+1);
        }
    }
    

    【讨论】:

    • 我不会说没有二维数组这样的东西。甲骨文似乎认为有。
    • 有二维数组这样的东西,只是在 Java 中没有。 Java 能做的最好的事情是对更多数组的引用的一维数组。这是不一样的,因为它们可能在堆上的任何地方。这意味着,如果您想要性能,有时您必须使用单个一维数组并自己计算索引。
    猜你喜欢
    • 2016-04-08
    • 1970-01-01
    • 2012-11-15
    • 2012-11-03
    • 1970-01-01
    • 1970-01-01
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多