代码之家  ›  专栏  ›  技术社区  ›  Corinna

Java中二维数组创建的尺寸向后看

  •  0
  • Corinna  · 技术社区  · 6 年前

    据我所知,Java中的二维数组是数组的数组。类似于通常的数组表示法,我希望这意味着

    int[][]
    

    实际上是

    (int[])[]
    

    (int数组的数组)。 因此我希望数组的长度

    int[][] array = new int[2][3]; // (int[2])[3] 
    

    为3(因为它是长度为3的数组,长度为2的数组)。 不过,情况似乎恰恰相反。

    我试图找到一个解释,但未能。我发现很多文章解释了如何初始化多维数组,它们是数组的数组,但是我找不到任何解释,为什么索引的顺序是这样工作的。

    我唯一的理论是,人们发现先对左索引进行迭代是更自然的,而Java是以这样一种方式构建的,这样操作效率更高,因此开发人员非常谨慎地做出了这种选择。

    我感谢任何来源证实这一解释或任何其他原因,为什么它这样做。


    编辑:既然人们似乎有些困惑,为什么有人会认为使用指数的另一种方法是一个好主意,这里有一些澄清:

    对于类型 T 表达 new T[5] 通常产生一个大小为5的数组。类型 int[] 似乎是一个非常好的类型,但是Java不允许我这么说 new (int[])[5] 而是强制我使用 new int[5][] . 我在寻找为什么Java会这样对我(并且得到一个)的原因。


    对于像我这样思考的人,我想补充一点(非常好的)答案:在一个没有人考虑过二维数组的世界里,你可以创建类型为 INT[] 与创建任何其他数组一样,以下代码可能是完全合法的代码。

        int[][] = new (int[])[5];
        int[] firstArray = new int[3];
        int[0] = firstArray;
        int[0][2] = 1; // last element of first array
        int[0][4] = 2; // IndexOutOfBoundsException, trying to access 5th element of firstArray
    

    这当然会完全混淆,所以我很高兴多维数组得到了特殊的处理。

    3 回复  |  直到 6 年前
        1
  •  4
  •   Andreas dfa    6 年前

    像这样的表情 new int[2][5] 将创建长度为2的外部数组,每个元素引用长度为5的数组,因此总共创建3个数组。这在Java语言规范中是有充分记载的。 Example 15.10.2-2. Multi-Dimensional Array Creation :

    声明:

    float[][] matrix = new float[3][3];
    

    在行为上等同于:

    float[][] matrix = new float[3][];
    for (int d = 0; d < matrix.length; d++)
        matrix[d] = new float[3];
    

    这并不意味着 (int[2])[5] ,即5个数组引用2个数组。

    因此,这个表达式 查找 从左到右计算值,例如 x[2][5] 方法 (x[2])[5] ,即,在 int[][] x 变量,查找 x[2] ,这是一个 int[] ,并在索引处的数组查找值中 5 .

    int[][] x = new int[9][9];
    // z = x[2][5]
    int[] y = x[2];
    int z = y[5];
    
        2
  •  2
  •   Chai T. Rex    6 年前

    原因是数组访问的重要性。你有一个数组( int[][] )然后从中检索数组( int[] )然后从中检索一个元素( int )

    有两种方法可以做到这一点。第一个是最重要的:

    for (int i = 0; i < matrix.length; i++) {
        int[] row = matrix[i];
        for int j = 0; j < row.length; j++) {
            int element = row[j];
        }
    }
    

    不得不使用 int[] row = matrix[][i]; 在第一个例子中,因为公约规定 array[i] 表示的第一个元素 array . 在这种情况下,第一个元素 数组 是行,不是元素。

    相同的索引顺序在整个过程中始终应用。


    这也与这样一个事实相一致,即你可以拥有一个具有奇怪维度的矩阵状物体 Object[] 阵列。也许这个数组的一个元素是 int[][][] 而下一个将是 INT[] . 要想办法弄清楚是否 array[][][][i] array[][i] 当你不知道子阵的维数时 i 子阵甚至不一定有一致的维数。

        3
  •  2
  •   Tim Biegeleisen    6 年前

    您可以将Java中的二维数组看作数组的数组。考虑以下一般二维数字数组:

    1 2 3
    4 5 6
    7 8 9
    

    我们 能够 将此数组定义为:

    int[][] array = new int[][] {{1,2,3}, {4,5,6}, {7,8,9}};
    

    或者,我们可以使用空构造函数,然后填充各个值:

    int[][] array = new int[3][3];
    array[0][0] = 1;
    array[0][1] = 2;
    // etc.
    

    但是为了更好地理解Java中的2D数组是如何工作的,请考虑以下方法:

    int[][] array = new int[3][];
    arr[0] = new int[] {1, 2, 3};
    arr[1] = new int[] {4, 5, 6};
    arr[2] = new int[] {7, 8, 9};
    

    希望能够清楚地知道二维数组的实际含义;它是数组的数组,因此我们可以将其可视化为:

    [ ] -> [1, 2, 3]
    [ ] -> [4, 5, 6]
    [ ] -> [7, 8, 9]
    

    也就是说,数组第一个索引中的每个元素(大小为3,对应于行)都指向另一个1D数组,对应于列。请注意,在Java中,二维数组可以是 锯齿状的 ,这意味着我们也可以这样做:

    int[][] array = new int[3][];
    arr[0] = new int[] {1, 2, 3, 4, 5};
    arr[1] = new int[] {1, 2, 3};
    arr[2] = new int[] {7, 7, 7};
    

    为了解决@henry在下面的评论中提出的问题,上面2d数组最左边部分的大小是3,这与我们画出来时看到的一致。也就是说,我们看到一个有3个桶的一维数组,每个桶指向另一个具有一定大小的一维数组。