前面我們學習的數組基本是基于一維數組來操作的,這一切我們就簡單的看一下二維數組。
二維數組,我們通俗點可以說成是數組中的數組,就是說我們可以把一個二維數組理解為一個元素為一維數組的一維數組。
二維數組的定義格式以下兩種格式:
格式一:
~~~
int[][] arr = new int[3][2];//定義了一個名為arr的二維數組,該二維數組中有3個一維數組,每一個一維數組中有2個元素
~~~
格式二:
~~~
int[][] arr = new int[3][];//這個沒有明確一維數組的長度
~~~
我們看看這兩種格式的不同之處,先看一段測試代碼:
~~~
class Array2Demo
{
public static void main(String[] args)
{
int[][] arr = new int[3][2];//定義一個名為arr的二維數組
System.out.println(arr);//直接打印二維數組 結果[[I@139a55,這是二維數組的地址
System.out.println(arr[0]);//直接打印二維數組中的索引0的一維數組 結果[I@1db9742,這是二維數組中索引0的一維數組的地址
System.out.println(arr[0][0]);//直接打印二維數組中索引0的一維數組索引0的元素 結果0,元素默認初始化為0
int[][] arr2 = new int[3][];//沒有明確一維數組的長度
//分別對二維數組中的每一個一維數組進行初始化
//arr2[0] = new int[2];
//arr2[1] = new int[1];
//arr2[2] = new int[3];
System.out.println(arr2);//直接打印二維數組 結果[[I@106d69c,這是二維數組的地址
System.out.println(arr2[0]);//直接打印二維數組中的索引0的一維數組 結果null,這是二維數組中索引0的一維數組沒有自動創建
//System.out.println(arr2[0][0]);//直接打印二維數組中索引0的一維數組索引0的元素 結果 NullPointerExcption
int[][] arr3 = new int[3][2];
System.out.println(arr3.length);//打印二維數組的長度,其實就是一維數組的個數.
System.out.println(arr3[1].length);//打印二維數組中索引為1的一維數組的長度.
}
}
~~~
結果:

從結果我們可以看兩種格式定義的二維數組打印數組會返回的都是數組的地址,從而我們進一步分析內在存儲為:
對于第一種格式,當運行時,先把arr變量存入棧中,然后在堆內存中為二維數組(實體)創建空間,并把數組的地址存入arr變量中,然后對每二維數組的每一個一維數組在堆內存中創建不同的空間,再分別把一維數組的地址存入一維數組中,最后對每一個一維數組的每一個元素進行默認初始化為0.
而對于第二種格式來說,對二維數組中的每一個一維數組都要進行初始化,當然對于這些數組初始化的大小可以不一樣,也就是第二種格式比第一種格式相對來說要靈活。如果我們不對一維數組進行初始化,就會出現上面代碼中運行的結果,打印二維數組的元素結果為null,打印一維數組的元素就會拋出NullPointerExcption異常。
這里我們知道第二種格式要比第一種格式定義的二維數組更靈活和實用。
前面我們學習了一維數組的幾種常用操作,這里我們就只看一下二維數組的遍歷操作。
當我們對一個二維數組遍歷的時候,我們很自然想到的就是前面學習for語句時的一種現象,那就大圈套小圈,誠然,對于二維數組的很多操作,我們最常用的也就是這個原理,循環的嵌套,下面我們看下學習過程中編寫的遍歷方法和測試結果:
~~~
class Array2Demo
{
public static void main(String[] args)
{
int[][] arr4 = {{3,1,4},{2,5,8},{4,3,9}};
//如何遍歷該二維數組?
//我們獨立寫一個遍歷的方法吧
printArray2(arr4);//結果:{{3,1,4},{2,5,8},{4,3,9}}
}
//這個方法用來遍歷一個二維數組
public static void printArray2(int[][] arr)
{
System.out.print("{");
for(int i=0;i<arr.length;i++)//很明顯就是大圈套小圈的原理
{
System.out.print("{");
for(int j=0;j<arr[i].length;j++)
{
System.out.print(arr[i][j]);
if(j<arr[i].length-1)//判斷去除最后一個逗號
{
System.out.print(",");
}
}
System.out.print("}");
if(i<arr.length-1)//判斷去除最后一個逗號
{
System.out.print(",");
}
}
System.out.print("}");
}
}
~~~
結果:

- 前言
- 1.1 基本常識
- 1.2 Java語言概述
- 1.3 Java語言的環境搭建
- 1.4 Java程序開發之初體驗--Hello World
- 2.1 關鍵字
- 2.2 標識符
- 2.3 注釋
- 2.4 常量
- 2.5 進制掃盲
- 2.6 變量和數據類型(1)
- 2.7 變量和數據類型(2)
- 2.8 運算符
- 3.1 if語句
- 3.2 switch語句
- 3.3 while和do-while語句
- 3.4 for語句
- 3.5 for循環的嵌套
- 3.6 break語句與continue語句
- 4.1 函數的定義
- 4.2 定義函數的兩個明確
- 4.3 函數的內存加載過程
- 4.4 函數的重載
- 5.1 數組的定義
- 5.2 數組的內存分配及特點
- 5.3 數組操作中常見問題
- 5.4 數組常用操作(1)
- 5.5 數組常用操作(2)
- 5.6 二維數組
- 6.1 面向對象的概述
- 6.2 類與對象的關系
- 6.3 對象的內存體現
- 6.4 成員變量與局部變量
- 6.5 類類型參數與匿名對象
- 6.6 基本數據類型參數與引用數據類型參數的傳遞過程
- 6.7 封裝
- 7.1 構造函數概述與默認構造函數
- 7.2 構造函數與一般函數的區別
- 7.3 構造函數的重載
- 7.4 構造函數的內存加載
- 7.5 構造函數需要注意的幾個細節
- 7.6 this關鍵字的原理
- 7.7 this關鍵字的細節與應用
- 8.1 static關鍵字之特點
- 8.2 成員變量與靜態變量的區別
- 8.3 static關鍵字使用的注意細節
- 8.4 main函數的解析與細節
- 8.5 static關鍵字的使用場景
- 8.6 靜態的內存加載
- 8.7 靜態代碼塊
- 8.8 構造代碼塊
- 9.1 繼承
- 9.2 單繼承與多重繼承
- 9.3 子父類中成員變量特征體現