多维数组
二维数组
二维数组的每个数组元素的长度并不要求相同。
public static void main(String[] args) {
int[][] ns = {
{ 1, 2, 3, 4 },
{ 5, 6 },
{ 7, 8, 9 }
};
System.out.println(ns.length); // 3
System.out.println(ns[2][2]); // 9
System.out.println(ns[1]); // 类似 [[I@5f184fc6 的无规则字符串
System.out.println(ns[1].toString()); // 类似 [[I@5f184fc6 的无规则字符串
System.out.println(Arrays.toString(ns[1])); // [5, 6]
}
如上二维数组在内存中的结构如下:
┌───┬───┬───┬───┐
┌───┐ ┌──>│ 1 │ 2 │ 3 │ 4 │
ns ─────>│░░░│──┘ └───┴───┴───┴───┘
├───┤ ┌───┬───┐
│░░░│─────>│ 5 │ 6 │
├───┤ └───┴───┘
│░░░│──┐ ┌───┬───┬───┐
└───┘ └──>│ 7 │ 8 │ 9 │
└───┴───┴───┘
JVM为二维数组分配了连续的内存单元存储三个元素,每个元素在内存单元中的内容是一维数组的 引用/内存地址。所以 System.out.println(ns[1])
打印的是内存单元中存储的内容,也就是一维数组的伪 引用/内存地址(因为会保护内存地址,得到的并不是真实的内存地址)。
需要调用 Arrays.toString
来打印数组。ns[1].toString()
并不是打印数组,执行时是"[[I@5f184fc6"
.toString(),字符串调用toString()方法输出结果不变。
遍历二维数组可以使用两层for循环:
public static void main(String[] args) {
int[][] ns = {
{ 1, 2, 3, 4 },
{ 5, 6 },
{ 7, 8, 9 }
};
for (int[] arr : ns) {
for (int n : arr) {
System.out.print(n+" ");
}
System.out.println();
}
}
三维数组甚至更高维
高维数组本质就是不断降维,结果都是指向一维数组的引用。
三维数组其实就是一个数组,该数组里每一个元素都是二维数组。
四维数组其实就是一个数组,该数组里面每一个元素都是三维数组。
更高维数组也是依此类推,不过一般三维数组都很少用,更高维就没必要了。
可以这么定义一个三维数组:
public static void main(String[] args) {
int[][][] ns = {
{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
},
{
{10, 11},
{12, 13}
},
{
{14, 15, 16},
{17, 18}
}
};
}
它在内存中的结构如下:
┌───┬───┬───┐
┌───┐ ┌──>│ 1 │ 2 │ 3 │
┌──>│░░░│──┘ └───┴───┴───┘
│ ├───┤ ┌───┬───┬───┐
│ │░░░│─────>│ 4 │ 5 │ 6 │
│ ├───┤ └───┴───┴───┘
│ │░░░│──┐ ┌───┬───┬───┐
┌───┐ │ └───┘ └──>│ 7 │ 8 │ 9 │
ns ────>│░░░│──┘ └───┴───┴───┘
├───┤ ┌───┐ ┌───┬───┐
│░░░│─────>│░░░│─────>│10 │11 │
├───┤ ├───┤ └───┴───┘
│░░░│──┐ │░░░│──┐ ┌───┬───┐
└───┘ │ └───┘ └──>│12 │13 │
│ └───┴───┘
│ ┌───┐ ┌───┬───┬───┐
└──>│░░░│─────>│14 │15 │16 │
├───┤ └───┴───┴───┘
│░░░│──┐ ┌───┬───┐
└───┘ └──>│17 │18 │
└───┴───┘
他の者にできたか?ここまでやれたか?この先できるか?いいや、仆にしかできない!