Java語言基礎(三)---陣列
Java語言基礎組成:關鍵字、識別符號、註釋、常量和變數、運算子、語句、函式、陣列
一. 陣列的定義:
同一種類型資料的集合,其實陣列就是一個容器。
運算時很多資料進行運算,先想到的不是運算,而是要把這些資料臨時儲存起來,以便於後期的運算。陣列就是儲存資料的一種方式。
【陣列的好處】:陣列能自動給存入元素進行編號,編號從0開始,方便操作這些元素。
【陣列的格式 1】: | 元素型別[ ] 陣列名 = new 元素型別[元素個數或陣列長度];
|
【陣列的格式 2】: (靜態儲存方式) |
元素型別[ ] 陣列名 = new 元素型別[ ]{ 元素1, 元素2, … };
|
二. 陣列的記憶體分配及特點:
任何一個應用程式在執行時,都要在記憶體中開闢空間,cpu處理完A程式才會再處理B程式。
Java程式在執行時,需要在記憶體中分配5個空間:棧記憶體、堆記憶體、方法區、本地方法區、暫存器。
【例項 1】 int x = 3 在記憶體中的分配情況。
【分析】:
- show函式執行完,show中的變數 x 就會在記憶體中消失。
- 如果show函式中有for迴圈語句:for (int x = 0; x < 5; x++) {}
那麼同樣的,for迴圈執行完,for迴圈中的變數 x 就會在記憶體中消失。
【棧的特點】:資料使用完畢,會自動釋放,變數會自動釋放。
【記憶體為什麼劃分出這麼多空間,劃分這麼細?】:
因為每一片記憶體空間中的資料處理方式不一樣,對於棧而言,資料使用完會自動釋放。
【例項 2】 分析在記憶體中的分配情況。
int[] x = new int[3];
x[0] = 59;
【分析】:
在棧記憶體中定義了x,凡是區域性變數都在棧記憶體中開闢空間。
區域性變數指 :
(1)定義在方法中的變數
(2)定義在方法引數上的變數。
(3)定義在for迴圈裡的變數等。new 出來的實體都在堆裡邊,堆裡邊存放的就是實體。實體為:陣列和物件。
【賦值】:將地址值賦值給變數x,賦值的不是陣列本身,而是陣列在記憶體中的地址。
陣列並沒有真正地存放在x 中去,只存放了地址,它在引用陣列而已。【指向】:變數x 有值了,稱為x 指向了這個陣列,或x 引用 了這個陣列。
【例項 3】 分析在記憶體中的分配情況。
int[] x = new int[3];
x = null;
【分析】:
- 只有引用資料型別,才能使用null。x = null =>表示 x 不再指向這個陣列,而且x 值為空。
- new int[3]在堆記憶體中沒有被任何人引用,就會被垃圾回收機制清除。(具體見堆特點3)
- 只有引用資料型別,才能使用null。x = null =>表示 x 不再指向這個陣列,而且x 值為空。
【堆的特點】:
堆記憶體中的每個實體,都有一個存放位置(記憶體地址值),記憶體裡都是二進位制的地址值,用地址來標識資料存放的位置,那麼這個陣列在記憶體中存放的時候,總有一個起始位置,即所謂的陣列指向。
陣列一旦被定義,裡邊的元素都有值,堆記憶體中的實體用了封裝資料的,都有預設初始化值。
int型陣列值:0
double型陣列值:0.0
float型陣列值:0.0f
boolean型陣列值:false
String型陣列值:null
char型陣列值:’\u0000’ (相當於空格)【垃圾回收機制】:陣列在堆記憶體中沒人使用了,當一個實體在堆記憶體中沒有任何引用所使用它的話,就視它為垃圾,或Java訓圾。這個垃圾不會立刻被記憶體清除掉,而是在不定時的時間內,啟動一個叫垃圾回收機制,將陣列實體在堆記憶體中清除。
C++語言:由程式設計師手動地呼叫一個功能將記憶體中的資料清除。
Java:程式設計師不用手動清除,只要這個物件或實體,在堆記憶體中已經變為垃圾,JVM會自動啟動垃圾回收機制,將堆記憶體中不再使用的實體清除。
【例項 4】分析在記憶體中的分配情況。
int[] x = new int[3];
int[] y = x;
y[1] = 89;
x = null;
/*【堆記憶體中有無垃圾?】
=> 沒有垃圾,x,y引用指向了同一個陣列物件,當x的值為空,不再指向陣列時,但是y仍指向陣列。
*/
【例項 5】分析在記憶體中的分配情況。
int[] x = new int[3];
int[] y = new int[3];
y[1] = 89;
x = null;
/**【堆記憶體中有無垃圾?】
=> 有垃圾。
只要是new的,記憶體中就會開闢新的空間,y指向的是新的陣列。
當x = null時,x之前指向的陣列,就無人指向,因而變為了垃圾。
*/
三. 陣列操作常見問題:
【例項 1】:陣列角標越界異常(ArrayIndexOutOfBoundsException )
public static void main(String[] args) {
int[] arr = {3, 1, 6};
System.out.println(arr[2]); //結果為:6
System.out.println(arr[3]); //[錯誤]
}
【分析】:
- 【編譯不報錯,執行出錯】:在Java編譯時並不建立實體,在執行時建立陣列,Java編譯只是檢查語法錯誤。
- 【錯誤提示 ArrayIndexOutOfBoundsException : 3】:
(1) [3]:陣列角標3越界。
(2) [ArrayIndexOutOfBoundsException]:陣列角標越界異常。
代表運算元組時,訪問到了陣列中不存在的角標。
所以在訪問陣列角標的時候,注意陣列角標不能大於陣列的長度,因為陣列角標是從0開始的。
【例項 2】:空指標異常(ArrayIndexOutOfBoundsException )
public static void main(String[] args) {
int[] arr = {3, 1, 6};
arr = null;
System.out.println(arr[1]); //[錯誤]
}
【分析】:
- 【編譯不報錯,執行出錯】:在Java編譯時並不建立實體,在執行時建立陣列,Java編譯只是檢查語法錯誤。
- 【錯誤提示 NullPointerException】: 空指標異常。
當沒有任何指向,值為null的情況,該引用還在用於操作實體,就會丟擲空指標異常。
四. 陣列常見操作:
1. 遍歷陣列
最為常見的獲取陣列中的元素,通常用遍歷,用for語句迴圈。【注】:角標最大值 = 陣列長度 - 1
陣列中有一個屬性可以直接獲取到陣列元素個數:陣列名稱.length
【注】:System.out.println(arr) 代表:把一個數組實體的引用給直接列印了。
輸出結果為[[email protected]
- 【 [ 】:左中括號,表示陣列
- 【 I 】:陣列的元素型別為 int
- 【62bc184】:陣列的記憶體存放地址,地址是由雜湊演算法計算出來的雜湊值(十六進位制),
因為十六進位制比較短所以採用十六進位制。
【例項 1】:求陣列和(【累加思想】:變數 + 迴圈)
public static void main(String[] args) {
int[] arr = {3, 1, 6};
System.out.println("sum = " + getArraySum(arr));
}
/**
* 功能:求出陣列的元素和
* @param arr 陣列
* @return 陣列元素和
*/
public static int getArraySum(int[] arr)
{
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
}
【例項 2】:定義一個功能,用於列印陣列中的元素,元素間用逗號隔開。
/**
* 功能:用於列印陣列中的元素,元素間用逗號隔開
* @param arr 陣列
*/
public static void printArray(int[] arr)
{
for (int i = 0; i < arr.length; i++)
{
if (i != arr.length - 1) //元素間逗號隔開
{
System.out.print(arr[i] + ",");
}
else
{
System.out.println(arr[i]);
}
}
}
【例項 3】:給定一個數組{5,1,6,4,2,8,9} 獲取陣列中的最大值,以及最小值。(只適用於數值型陣列)
/**
* 方法一:求max
* 1. 定義變數max,初始化為陣列中仁義一個元素值即可,max = arr[0]
* 2. 通過迴圈語句,對陣列進行遍歷
* 3. 在變數中定義判斷條件,如果遍歷到的元素比變數中的元素大,就賦值給變數。
* @param arr 陣列
* @return 最大值
*/
public static int getMax(int[] arr)
{
int max = arr[0];
for (int i=1; i<arr.length; i++)
{
if(max < arr[i])
max = arr[i];
}
return max;
}
/**
* 方法二:求max
* 1. 定義變數max,初始化為陣列中的任意一個角標,max = 0
* 2. 通過迴圈語句,對陣列進行遍歷
* 3. 在變數中定義判斷條件,如果遍歷到的元素比arr[max]中的元素大,就將元素角標賦值給變數。
* @param arr 陣列
* @return 最大值
*/
/*public static int getMax(int[] arr)
{
int max = 0;
for (int i = 1; i < arr.length; i++)
{
if(arr[max] < arr[i])
max = i;
}
return arr[max];
}*/
//獲取double型別陣列的最大值,因為功能一致,所以定義相同函式名稱,以過載方式存在。
public static double getMax(double[] arr)
{
}
/**
* 求min
* @param arr 陣列
* @return 最小值
*/
public static int getMin(int[] arr)
{
int min = arr[0];
for (int i=1; i<arr.length; i++)
{
if(min > arr[i])
min = arr[i];
}
return min;
}
2. 陣列排序
【排序的方法】:
氣泡排序 :相鄰兩個元素進行排序,如果符合條件則換位。
特點:內迴圈結束一次,最值出現在最後位。選擇排序:選擇固定位置的值,不斷地和其他元素進行比較,符合條件則換位,接著拿這個位置上的值進行比較。
特點:內迴圈結束一次,最值出現在頭角標位置上。插入排序:需要排序的陣列越有序,插入排序的效率越高。
希爾排序(是最快的排序,三層迴圈加上位運算):
將需要排序的陣列分割成小的子陣列,對這個子陣列進行插入排序,排序後越來越接近有序的陣列。快速排序
歸併排序
工具類Arrays:
在Java中, 已經定義好了一種排序方式,是使用到了專門運算元組的工具類Arrays。
Arrays有一個靜態方法sort可以對陣列進行排序。例如:Arrays.sort(arr);
【例項】 對給定陣列進行排序。{5,1,6,4,2,8,9}
(1)方法一:選擇排序
【選擇排序】:選擇固定位置的值不斷和別人進行比較,交換位置後,依舊拿這個位子的值與別人比較。
【選擇排序的特點】:內迴圈結束一次,最值出現在頭角標位置上,前面逐級進行排序
【例項】:程式碼體現
public static void main(String[] args) {
int[] arr = {5,1,6,4,2,8,9};
System.out.println("-------------排序前-------------");
printArray(arr);
selectSort(arr); //選擇排序
System.out.println("-------------排序後-------------");
printArray(arr);
}
/**
* 選擇排序
* @param arr 陣列
*/
public static void selectSort(int[] arr)
{
for (int i = 0; i < arr.length - 1; i++) { //不需要遍歷最後一個角標,所以arr.length - 1
for(int j = i + 1; j < arr.length; j++) //每個元素與後面進行比較,所以i + 1
{
if(arr[i] > arr[j])
{
swap(arr, i, j); //兩數交換
}
}
}
}
/**
* 交換陣列中的兩個元素
* @param arr 陣列
* @param i 陣列角標i
* @param j 陣列角標j
*/
public static void swap(int[] arr, int i, int j)
{
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
}
/**
* 列印陣列
* @param arr 陣列
*/
public static void printArray(int[] arr)
{
for (int i = 0; i < arr.length; i++) {
if( i != arr.length -1)
{
System.out.print(arr[i] + ", ");
}
else
{
System.out.println(arr[i]);
}
}
}
(2)方法二:氣泡排序
【氣泡排序】:相鄰的兩個元素進行排序,如果符合條件換位。
【氣泡排序的特點】:
每次迴圈都是從0角標開始的。
第一圈最值出現在最後位。
- 第二次比較的特點:參與比較元素的長度 -1,逐漸減小。
【例項 1】:程式碼體現
public static void main(String[] args) {
int[] arr = {5,1,6,4,2,8,9};
System.out.println("-------------排序前-------------");
printArray(arr);
bubbleSort(arr); //氣泡排序
System.out.println("-------------排序後-------------");
printArray(arr);
}
/**
* 氣泡排序
* @param arr 陣列
*/
public static void bubbleSort(int[] arr)
{
for (int i = 0; i < arr.length - 1; i++) { //共迴圈比較arr.length - 1圈
for (int j = 0; j < arr.length - i -1; j++) { //-i:讓每次比較的元素減少; -1:避免角標越界
if(arr[j] > arr[j + 1])
{
swap(arr, j, j + 1); //兩數交換,但是直接換位置,效能低,一圈中要換好幾次
}
}
}
}
/**
* 交換陣列中的兩個元素
* @param arr 陣列
* @param i 陣列角標i
* @param j 陣列角標j
*/
public static void swap(int[] arr, int i, int j)
{
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
}
/**
* 列印陣列
* @param arr 陣列
*/
public static void printArray(int[] arr)
{
for (int i = 0; i < arr.length; i++) {
if( i != arr.length -1)
{
System.out.print(arr[i] + ", ");
}
else
{
System.out.println(arr[i]);
}
}
}
【例項 2】:氣泡排序的更優解(每一圈取出最值的角標,與最後的角標交換位置)
如果兩個數需要換位置的話,先不要置換它們的位置,先把它們需要換位置的角標及元素記錄下來。
在棧記憶體中,定義兩個變數,臨時記錄下來,全都比較完後,取最終需要換位置的值就可以了。
把堆記憶體中頻繁地換位置,轉移到棧記憶體中。
public static void main(String[] args) {
int[] arr = {5,1,6,4,2,8,9};
System.out.println("-------------排序前-------------");
printArray(arr);
bubbleSort(arr); //氣泡排序
System.out.println("-------------排序後-------------");
printArray(arr);
}
/**
* 氣泡排序
* @param arr 陣列
*/
public static void bubbleSort(int[] arr)
{
for (int i = 0; i < arr.length - 1; i++) {
int j = 0, max = 0; //max 記錄最大值的角標
for (j = 1; j < arr.length - i; j++) {
if(arr[j] > arr[max])
{
max = j;
}
}
if(j-1 != max) //如果max 角標不等於最後一個角標,兩數交換
{
swap(arr, j-1, max); //兩數交換
}
}
}
/**
* 交換陣列中的兩個元素
* @param arr 陣列
* @param i 陣列角標i
* @param j 陣列角標j
*/
public static void swap(int[] arr, int i, int j)
{
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
}
/**
* 列印陣列
* @param arr 陣列
*/
public static void printArray(int[] arr)
{
for (int i = 0; i < arr.length; i++) {
if( i != arr.length -1)
{
System.out.print(arr[i] + ", ");
}
else
{
System.out.println(arr[i]);
}
}
}
(3)方法三:直接插入排序
【插入排序】:將一個元素插入到已經排好序的陣列中去,從而得到一個新的陣列長度 + 1 的有序陣列。
【插入排序的原理】:
假設陣列為一個有序陣列。
每次判斷陣列元素是否大於前一個數,如果小於的話,就往前遍歷陣列,將大於這個數的元素往後移,將這個數放入到具體位置,使陣列依然為有序陣列。
【例項】:程式碼體現(針對 insterSort 方法)
/**
* 直接插入排序
* @param arr 陣列
*/
public static void insterSort(int[] arr)
{
for (int i = 1; i < arr.length; i++) { //由角標1開始遍歷陣列
if(arr[i] < arr[i-1]) //判斷陣列元素是否大於前一個數
{
int temp = arr[i], j;
for (j = i - 1; j >= 0 && arr[j] > temp; j--) { //陣列往後移動
arr[j + 1] = arr[j];
}
arr[j + 1] = temp;
}
}
}
(4)方法四:希爾排序
【希爾排序】:把陣列進行分組,分割成若干個子序列,然後對子序列進行基本的插入排序。
【希爾排序的原理】:
- 普通的插入排序:判斷間隔間隔為1
- 希爾排序:判斷間隔為space,並且間隔不斷縮小(除2操作)直到為0。
【例項 】:程式碼體現
/**
* 直接插入排序 + 希爾排序 + space取整
* @param arr 陣列
*/
public static void shellSort(int[] arr)
{
int space = arr.length;
do
{
space >>= 1; // space = space/2;
for (int i = space; i < arr.length; i++) { //在直接排序的基礎上,將間隔1,改為space
if(arr[i] < arr[i-space])
{
int temp = arr[i], j;
for (j = i - space; j >= 0 && arr[j] > temp; j -= space) {
arr[j + space] = arr[j];
}
arr[j + space] = temp;
}
}
}while(space > 0);
}
3. 查詢陣列
陣列的查詢操作:在遍歷中進行判斷。
【查詢陣列的方法】:
簡單查詢:直接遍歷陣列進行匹配
折半查詢:折中找中間值,提高效率,但必須要保證該陣列是有序的陣列。
【例項】 定義功能,獲取key第一次出現在陣列中的位置,如果返回是-1,那麼代表該key在陣列中不存在
(因為陣列下標不會存在-1)
- (1) 方法一:從0角標遍歷陣列,進行查詢
/**
* 獲取key第一次出現在陣列中的位置
* @param arr 陣列
* @param key 匹配的資料
* @return 陣列角標或-1,如果為-1,沒有找到key
*/
public static int getIndex(int[] arr, int key)
{
for (int i = 0; i < arr.length; i++) {
if(key == arr[i])
{
return i;
}
}
return -1;
}
- (2) 方法二:折半查詢
/**
* 獲取key第一次出現在陣列中的位置
* @param arr 陣列
* @param key 匹配的數
* @return 陣列角標或 -1
*/
public static int halfSearch(int[] arr, int key)
{
int min = 0, max = arr.length - 1, mid;
while(min <= max) //當min>max, 迴圈結束
{
mid = (min + max) >> 1; //獲得mid
if(key > arr[mid])
{
min = mid + 1;
}
else if(key < arr[mid])
{
max = mid - 1;
}
else
{
return mid;
}
}
return -1;
}
4. 插入元素
【例項】 有個有序的陣列,想要將一個元素插入到該陣列中,還要保證該陣列是有序的。
【思路】:通過折半的形式去查詢這個數,在陣列中的位置,如果這個數存在,在這個位置上把這個數插入,如果不存在,返回最小角標的值,就可以得到要插入的位置。
/**
* 折半查詢,獲取插入元素的角標
* @param arr 陣列
* @param num 要插入的元素
* @return 要插入元素的角標
*/
public static int halfSearch(int[] arr, int num)
{
int min = 0, max = arr.length - 1, mid;
while(min <= max)
{
mid = (min + max) >> 1;
if(num > arr[mid])
{
min = mid + 1;
}
else if(num < arr[mid])
{
max = mid - 1;
}
else
{
return mid;
}
}
return min;
}
/**
* 將元素插入的相應的位置上,獲得新陣列
* @param arr 陣列
* @param index 要插入的角標
* @param num 元素值
* @return 新陣列
*/
public static int[] getNewArray(int[] arr, int index, int num)
{
int[] rtnArr = new int[arr.length + 1];
for (int i = 0; i < index; i++) {
rtnArr[i] = arr[i];
}
rtnArr[index] = num; //插入元素到指定位置
for (int i = index; i < arr.length; i++) {
rtnArr[i + 1] = arr[i];
}
return rtnArr;
}
5. 進位制轉換
(1)十進位制轉換二進位制
/**
* 十進位制轉換二進位制
* @param num 十進位制數
* @return 二進位制(以字串形式返回)
*/
public static String toBin(int num)
{
StringBuilder sb = new StringBuilder();
while(num > 0) //有侷限,負數無法求出
{
sb.append(num % 2 );
num >>= 1;
}
return sb.reverse().toString();
}
【查表法】:將所有的元素臨時儲存起來,建立對應關係,每一次&運算後的值作為索引去查建立好的表,就可以找到對應的元素(不用強制轉換了)
【利用查表法,更改上面的十進位制轉換】
/**
* 進製表
*/
final static char[] digits = {
'0' , '1' , '2' , '3' , '4' , '5' ,
'6' , '7' , '8' , '9' , 'a' , 'b' ,
'c' , 'd' , 'e' , 'f'
};
/**
* 十進位制轉換二進位制
* @param num 十進位制數
* @return 二進位制(以字串形式返回)
*/
public static String toBin(int num)
{
StringBuilder sb = new StringBuilder();
while(num != 0)
{
int temp = num & 1;
sb.append(digits[temp]); //利用查表法,直接獲取對應值
num >>>= 1;
}
return sb.reverse().toString();
}
(2)十進位制轉換十六進位制
/**
* 進製表
*/
final static char[] digits = {
'0' , '1' , '2' , '3' , '4' , '5' ,
'6' , '7' , '8' , '9' , 'a' , 'b' ,
'c' , 'd' , 'e' , 'f'
};
/**
* 十進位制轉換二進位制
* @param num 十進位制數
* @return 二進位制(以字串形式返回)
*/
public static String toHex(int num)
{
StringBuilder sb = new StringBuilder();
while(num != 0)
{
int temp = num & 15;
/*if(temp > 9)
{
sb.append((char)(temp-10 + 'a'));
}
else
{
sb.append(temp);
}*/
sb.append(digits[temp]);
num >>>= 4;
}
return sb.reverse().toString();
}
(3)十進位制轉換各種進位制(升級版)
/**
* 進製表
*/
final static char[] digits = {
'0' , '1' , '2' , '3' , '4' , '5' ,
'6' , '7' , '8' , '9' , 'a' , 'b' ,
'c' , 'd' , 'e' , 'f'
};
public static void main(String[] args) {
System.out.println(toBin(0));
System.out.println(toHex(-60));
}
/**
* 十進位制轉各種進位制數
* @param num 十進位制數
* @param base &運算的基數
* @param offset >>>位移多少位
* @return
*/
public static String trans(int num, int base, int offset)
{
if(num == 0) // 不然當0的時候,沒有值
{
return "0";
}
StringBuilder sb = new StringBuilder();
while(num != 0)
{
int temp = num & base;
sb.append(digits[temp]);
num >>>= offset;
}
return sb.reverse().toString();
}
/**
* 十進位制轉換二進位制
* @param num 十進位制數
* @return 二進位制(以字串形式返回)
*/
public static String toBin(int num)
{
return trans(num, 1, 1);
}
/**
* 十進位制轉換十六進位制
* @param num 十進位制數
* @return 十六進位制(以字串形式返回)
*/
public static String toHex(int num)
{
return trans(num, 15, 4);
}
/**
* 十進位制轉換八進位制
* @param num 十進位制數
* @return 八進位制(以字串形式返回)
*/
public static String toOctal(int num)
{
return trans(num, 7, 3);
}
五. 二維陣列:
陣列中的陣列:往陣列中存放陣列,把陣列作為元素存入另一個數組中。
1. 二維陣列的定義:
【一維陣列】: | int[ ] arr = new int[3]; |
【二維陣列】: |
【陣列的格式 1】 int[ ] arr = new int[3][4];
|
【陣列的格式 2】 int[ ] arr = new int[3][ ];
|
|
【陣列的格式 3】(靜態儲存方式) int[ ] arr = { {3, 5, 7}, {2, 3, 5}, {6, 1, 8, 2} };
|
|
【一維陣列 與 二維陣列的小知識】: 1. 一維陣列:int[ ] x = int x[ ] 2. 二維陣列:int[ ][ ] x = int x[ ][ ] = int[ ] x[ ] 【例項】int[ ] x, y[ ]; => int[ ] x, int[ ] y[ ]; 1. [ ] 定義在型別中,是隨型別走的,而型別的[ ],變數都有效 2. [ ] 定義在變數後,是隨著變數走的,只有單個變數有效。 (1)x[0] = y [錯誤] (2)y[0] = x [正確] (3)y[0][0] = x [錯誤] (4)x[0][0] = y [錯誤] (5)y[0][0] = x[0] [正確] (6)x = y [錯誤] |
2. 二維陣列的記憶體分配:
- (1)【陣列的格式 1】 的記憶體分配
【例項】列印二維陣列地址值
int[][] arr = new int[3][4];
System.out.println(arr); //[[[email protected]
System.out.println(arr[0]); //[[email protected]
/*
二維陣列的首地址:兩個左中括號
一維陣列的首地址:一個左中括號
*/
- (2)【陣列的格式 2】 的記憶體分配(不規則陣列)
【分析】:
- int[ ][ ] arr = new int[3][ ];
這個二維陣列中的一維陣列沒有初始化,用的是預設初始化,而陣列是引用資料型別,所以初始化值都為空,也就是這3個一維陣列變數(e.g. arr[0])沒有任何的小陣列指向。 - arr[0] = new int[3];
對二維陣列中每一個小陣列進行手動初始化。初始化後,把陣列地址賦值給arr[0]。
【例項】列印二維陣列地址值
int[][] arr = new int[3][];
System.out.println(arr); //[[[email protected]
System.out.println(arr[0]); //null (一維陣列沒有指定)
arr[0] = new int[3];
arr[1] = new int[1];
arr[2] = new int[2];
arr[0][2] = 90;
arr[1][1] = 89;
arr[2][2] = 78;
System.out.println(arr.length); //結果為:3
System.out.println(arr[0].length); //結果為:3 列印二維陣列中第一個一維陣列的長度