【问题标题】:Thorough understanding of any multi-dimensional array in Java深入理解Java中的任何多维数组
【发布时间】:2013-04-26 01:39:32
【问题描述】:

我是一名Java初学者,之前曾问过多维数组问题,但没有一个答案是清晰简洁的。

例如,当一个二维数组被这样初始化时:

int[][] a = {{1,2,3}}

这只是意味着元素“1”是“第 1 行,第 1 列”,元素“2”是“第 1 行,第 2 列” 但是呢

int[][][] b = {{1,2,3}}

这是否意味着元素“1”是 3-D 数组 b 中的“1 x, 1 y, 1 z”?

这样说的多维数组怎么样:

int[][][][] c = {{1,2,3}}

你会怎么想?这是因为我读过的每一本教科书都没有描述一个超过二维数组的数组。他们会简单地说,存在无数维数组。但我无法想象它们。

请帮助我尽可能清楚地回答这个问题,以便任何其他用户只需阅读答案即可完全掌握任何多维数组。

【问题讨论】:

  • int[][] a = {1,2,3} 在 Java 中无效!
  • functionx.com/java/Lesson22.htm多维数组部分应该会有所帮助。
  • @Eng.Fouad 语法更正
  • 我只想提一下,在 Java 中处理多维数组很少是一个好的答案。列表列表更容易构思和处理。此外,无论您使用什么——将它封装在一个类中——不要随意传递它......但这是一个有效的问题......理解特性,即使是那些你可能不应该使用的特性,也很重要。

标签: java arrays multidimensional-array


【解决方案1】:

您的代码示例都不是合法的 Java。本声明:

int[][] a;

a 声明为int 数组的数组。 (Java 实际上没有二维数组。)您可以使用数组数组对其进行初始化:

int[][] a = { {1, 2, 3}, {4, 5, 6} };

但是,您不能使用{1, 2, 3} 进行初始化,因为{1, 2, 3}int[],而不是int[][](也就是说,“int 的数组”与“int 的数组”的类型不同int")。

类似的考虑也适用于其他情况。例如:

int[][][][] c;

声明int的数组数组数组。

一旦你理解了数组数组的基本概念,理解具体的声明就不难了。例如:

int[][][] b = new int[3][4][2];

声明b 是一个长度为3 的数组。b 的每个元素是一个由4 个数组组成的数组,每个数组是一个由2 个int 值组成的数组。像往常一样,所有int 值都初始化为0。您不必初始化尾随维度:

int[][][] b = new int[3][][];

声明 b 是一个 3 长的数组。每个元素都必须是int[][],但最初所有元素都是null

不要求元素具有相同的长度。因此,例如,b[1] 可能设置为长度为 7 的数组,而 b[2] 可能设置为长度为 12。

Java Language Specification 详细介绍了数组创建。

【讨论】:

  • 我还是没明白!那么 int[][][][] = {{1,2,3}, {3,4,5}} 与您的二维数组有何不同
  • @user2282158 - 我稍微扩展了我的答案。看看这是否解决了您的问题。
  • 例如 int[][][] b = new int[3][4][2];数组的长度如何为三?是不是因为它有三个方括号?
  • @user2282158 - 因为new 运算符中的第一个维度是 3。
  • 好吧,比如说 int[][][][] d = new int[4][5][6][7],是不是表示数组的长度为 4 呢?其他维度?你能给我一个固定的规则,就像你说的第一个维度总是数组的长度,那么它的连续维度必须是什么?就像你的 3-D 数组一样,你说 [][][] = [length][size of each element in the array][size of the each element in the previous array] 它会像这样滚动吗?
【解决方案2】:

请结合@Ted Hopp 的回答阅读本文。

我只是想解释一下为什么你给出的例子不是有效的Java。

int[][] a = {{1,2,3}}

这(现在)有效(除了末尾缺少的分号)

int[][][] b = {{1,2,3}}

这是无效的,因为数组初始值设定项指定了一个 2-D 数组,而您正在将它分配给一个 3-D 数组。

int[][][][] c = {{1,2,3}}

这是无效的,因为数组初始值设定项指定了一个二维数组,而您将它分配给一个 4 维数组。

事实上,这应该可以消除您对在这些情况下会发生什么的担忧。答案是什么。该代码是非法的。声明的数组类型和初始化器的维度必须相同。


关于这样创建的矩形阵列(或 N 维类似物)。

int[][][][] d = new int[4][5][6][7];

每个维度的长度可以简单地从初始化器中读取;即声明 Java 等效于 4x5x6x7 4-D 矩阵。你也可以在代码中做到这一点。

System.out.println(d.length);   // prints 4 
System.out.println(d[0].length);   // prints 5 
System.out.println(d[0][0].length);   // prints 6
System.out.println(d[0][0][0].length);   // prints 7

你也可以用参差不齐的数组来做到这一点......除了你会发现各种子数组的长度不统一。相反,它们取决于初始化器中各个子数组的大小,或者其他什么。


这是因为我读过的每一本教科书都没有描述一个超过二维数组的数组。

为教科书作者辩护:

  1. 真正的 Java 程序使用二维以上的数组是不常见的,使用{{{...}}} 样式初始化器来初始化它们更不常见。

  2. 事实上,用于一维和二维数组的相同模式确实以一种自然而明显的方式扩展到更高维数组。 (或者至少,这对大多数 Java 程序员来说是自然而明显的......)

因此,在教科书上花费额外的页数来解释“显而易见”和“很少使用”的东西很难证明是合理的,尤其是如果这意味着从书中其他地方删减材料。

而且 FWIW,典型的 Java 教科书也没有提及 Java 语言的其他晦涩角落,如标签中断、初始化块、变量名中的“$”、Java 名称解析规则等。这可能是一件好事1


1 - 是的...我一直在阅读“1066 和所有这些”。

【讨论】:

  • 进一步说明 int[] a = {{1,2,3}} 与二维数组有何不同:int[][] a = {{1,2,3}}跨度>
  • 非常感谢,我想澄清一点:对于 int[4][5][6][7],您将有 4 个组。四个组中的每一个都被制成 4 个列表。这 4 个列表中的每一个都有 6 个元素,其中每个元素都是一个数组,每个元素都有 7 个元素?所以基本上,第一个维度是长度,任何其他维度基本上是前面数组中数组的长度。是吗?
  • "int[] a = {{1,2,3}}" 版本是一个编译错误,原因与 "int[][][][] c = {{1 ,2,3}}" 是编译错误。请再次阅读我的回答。
  • 您的其他评论对我来说没有任何意义。我不知道您在说什么“组”,或者您将它们分成 4 个列表是什么意思,或者这 6 个元素来自哪里。你完全把我弄糊涂了。
  • 别担心斯蒂芬,我明白了。谢谢。
【解决方案3】:

当我第一次遇到多维数组时,我自己也很难理解这个概念。

首先将二维数组视为图像。每个元素都是一个像素。

3D 数组就是电影。 [i, j, k] 处的元素是电影第 k 帧中坐标 (i, j) 处的像素。

4D数组是由多个摄像机组成的电影,[i,j,k,l]是第l个摄像机第k帧坐标(i,j)处的像素。

想一想这样的多维数组,过了一会儿,你就会完全忽略它的维数。

祝你好运!

【讨论】:

  • 是的,但我现在更自然了。
【解决方案4】:

实际上,Java 使用的是交错数组,即数组的数组。

int[][] array = {{1, 2}, {3, 4}};

而在 C# 等其他语言中,它们具有多维数组(除了锯齿状数组):

string[,] array = new string[2,3];

【讨论】:

    【解决方案5】:

    这是您声明和初始化 1D、2D、3D 和 4D 数组的方式:

    int[] oneD = {1,2,3,4,5,6};
    int[][] twoD = { {1,2,3}, {4,5,6} };
    int[][][] threeD = { { {1,2,3,4,5}, {2,3}, {3}}, {{4}, {5,6,6,7}, {10,6,7} } };
    int[][][][] fourD = { { { {1,1}, {2}},{{1,2}, {3}}, {{3}, {4,5,6,7,8,9,10}}}, {{{4},{5,6,7}}, {{5},{6}}, {{6,1,2},{0,7} } } };  
    

    【讨论】:

    • 好吧,比如说 int[][][][] d = new int[4][5][6][7],是不是表示数组的长度是 4 呢?其他维度?你能给我一个固定的规则,比如你说第一个维度总是数组的长度,那么它的连续维度必须是什么?就像你的 3-D 数组一样,你说 [][][] = [length][size of each element in the array][size of the each element in the previous array] 它会像这样滚动吗?
    • 尝试先获得 3D,然后根据相同的规则转到 4D。因此,对于int[4][5][6] 3D 阵列,您将有四个组。四个组中的每一个都由五个列表组成。每个列表包含六个数字。所以 3D 数组将包含 4 * 5 * 6 = 120 ints。
    • 因此对于 int[4][5][6][7],您将有 4 个组。四个组中的每一个都被制成 4 个列表。这 4 个列表中的每一个都有 6 个元素,其中每个元素都是一个数组,每个元素都有 7 个元素?
    • 所以基本上,第一个维度是长度,之前的任何其他维度基本上是前面数组中数组的长度。是吗?
    • 是的。为了减少混淆,您有 4 个列表,每个列表包含 5 个列表,每个列表包含 6 个列表,每个列表包含 7 个数字。 :)