ARRAY
ARRAY陣列111
※陣列在JAVA是物件型態
陣列元素初始值 資料型態 初始值 byte 0 short 0 int 0 long 0L float 0.0f double 0.0d char \u0000 boolean false
5.1.2 二維陣列物件
一維陣列使用「名稱」與「一個索引」來指定存取陣列中的元素,您也可以宣告二維陣列,二維陣列使用「名稱」與「兩個索引」來指定存取陣列中的元素,其宣告方式與一維陣列類似:
int[][] arr = {{1, 2, 3}, {4, 5, 6}};
從上面這個程式片段來看,就可以清楚的看出二維陣列的索引方式,您宣告了 2 列(Row)3 行(Column)的陣列,使用 { } 與適當的斷行可以協助您指定陣列初值,範例 5.5 簡單的示範二維陣列的存取。 範例 5.5 TwoDimArray.java
public class TwoDimArray { public static void main(String[] args) { int[][] arr = {{1, 2, 3}, {4, 5, 6}};
for(int i = 0; i < arr.length; i++) {
for(int j = 0; j < arr[0].length; j++)
System.out.print(arr[i][j] + " ");
System.out.println();
}
}
}
執行結果:
1 2 3 4 5 6
陣列值 arr[i][j] 表示指定的是第 i 列第 j 行的值。在使用二維陣列物件時,注意 length 所代表的長度,陣列名稱後直接加上 length(如 arr.length),所指的是有幾列(Row);指定索引後加上 length(如 arr[0].length),指的是該列所擁有的元素,也就是行(Column)數目。
從圖 5.1 中您可以看到,arr 參考至 int[][] 形態的物件,而 arr[0] 與 arr[1] 再分別參考至一個 int[] 物件,所以範例 5.5 中,使用的 arr.length 得到的是 2,而 arr[0].length 得到的長度是 3。有了陣列配置的觀念,您可以改寫範例 5.5 為範例 5.6,讓程式中的 int[] 型態之名稱 foo 來循序取出 arr[0] 與 arr[1] 所參考的 int[] 物件中的每個元素值,執行結果是相同的。 範例 5.6 TwoDimArray2.java
public class TwoDimArray2 { public static void main(String[] args) { int[][] arr = {{1, 2, 3}, {4, 5, 6}};
int[] foo = arr[0]; // 將arr[0] 所參考的陣列物件指定給foo
for(int i = 0; i < foo.length; i++) {
System.out.print(foo[i] + " ");
}
System.out.println();
foo = arr[1]; // 將arr[1] 所參考的陣列物件指定給foo
for(int i = 0; i < foo.length; i++) {
System.out.print(foo[i] + " ");
}
System.out.println();
}
}
如果在使用 new 配置二維陣列後想要一併指定初值,則可以如下撰寫:
int[][] arr = new int[][] {{1, 2, 3}, {4, 5, 6}};
同樣的道理,您也可以宣告三維以上的陣列,如果要同時宣告初始元素值,可以使用以下的簡便語法:
int[][][] arr = { {{1, 2, 3}, {4, 5, 6}}, {{7, 8, 9}, {10, 11, 12}} };
「不規則陣列」。陣列的維度不一定要是四四方方的,您也可以製作一個二維陣列,而每個維度的長度並不相同,範例 5.7 是個簡單的示範。 範例 5.7 TwoDimArray3.java
public class TwoDimArray3 { public static void main(String[] args) { int arr[][];
arr = new int[2][];
arr[0] = new int[3]; // arr[0] 參考至長度為3的一維陣列
arr[1] = new int[5]; // arr[1] 參考至長度為5的一維陣列
for(int i = 0; i < arr.length; i++) {
for(int j = 0; j < arr[i].length; j++)
arr[i][j] = j + 1;
}
for(int i = 0; i < arr.length; i++) {
for(int j = 0; j < arr[i].length; j++)
System.out.print(arr[i][j] + " ");
System.out.println();
}
}
}
這個例子只是先前說明之觀念延伸,在這個例子中,陣列第一列的長度是3,而第二列的長度是 5,執行結果如下:
1 2 3 1 2 3 4 5
5.2.1 進階的陣列操作
藉由對陣列物件的進一步探討,您可以稍微瞭解 Java 對物件處理的一些作法,首先來看看一維陣列的參考名稱之宣告:
int[] arr = null;
在這個宣告中,arr 表示一個可以參考至 int 一維陣列物件的參考名稱,但是目前您將這個名稱參考至 null,表示這個名稱參考還沒有參考至實際的物件,在 Java 中,'=' 運算用於基本資料型態時,是將值複製給變數,但當它用於物件時,則是將物件指定給參考名稱來參考,您也可以將同一個物件指定給兩個參考名稱,當物件的值藉由其中一個參考名稱進行操作而變更時,另一個參考名稱所參考到的值也會更動,來看看範例 5.8 的示範。 範例 5.8 AdvancedArray.java
public class AdvancedArray { public static void main(String[] args) { int[] arr1 = {1, 2, 3, 4, 5}; int[] tmp1 = arr1; int[] tmp2 = arr1;
System.out.print("透過tmp1取出陣列值:");
for(int i = 0; i < tmp1.length; i++)
System.out.print(tmp1[i] + " ");
System.out.print("\n透過tmp2取出陣列值:");
for(int i = 0; i < tmp2.length; i++)
System.out.print(tmp2[i] + " ");
tmp1[2] = 9;
System.out.print("\n\n透過tmp1取出陣列值:");
for(int i = 0; i < tmp1.length; i++)
System.out.print(tmp1[i] + " ");
System.out.print("\n透過tmp2取出陣列值:");
for(int i = 0; i < tmp2.length; i++)
System.out.print(tmp2[i] + " ");
System.out.println();
}
}
執行結果:
透過tmp1取出陣列值:1 2 3 4 5 透過tmp2取出陣列值:1 2 3 4 5
透過tmp1取出陣列值:1 2 9 4 5 透過tmp2取出陣列值:1 2 9 4 5
您瞭解到在 Java 中陣列是一個物件,而使用 '=' 指定時是將物件指定給陣列名稱來參考,也就是相當於圖 5.3 中改變名稱所綁定的物件,而不是將陣列進行複製,如果您想將整個陣列的值複製給另一個陣列該如何作呢?您可以使用迴圈,將整個陣列的元素值走訪一遍,並指定給另一個陣列相對應的索引位置,範例 5.10 示範了進行陣列複製的方法。 範例 5.10 ArrayCopy.java
public class ArrayCopy { public static void main(String[] args) { int[] arr1 = {1, 2, 3, 4, 5}; int[] arr2 = new int[5];
for(int i = 0; i < arr1.length; i++)
arr2[i] = arr1[i];
for(int i = 0; i < arr2.length; i++)
System.out.print(arr2[i] + " ");
System.out.println();
}
}
執行結果:
1 2 3 4 5
另一個進行陣列複製的方法是使用 System 類別所提供的 arraycopy() 方法,其語法如下:
# System.arraycopy(來源, 起始索引, 目的, 起始索引, 複製長度);
範例 5.11 改寫了範例 5.10,使用 System.arraycopy() 進行陣列複製,執行結果與範例 5.10 是相同的。 範例 5.11 ArrayCopy2.java
public class ArrayCopy2 { public static void main(String[] args) { int[] arr1 = {1, 2, 3, 4, 5}; int[] arr2 = new int[5];
System.arraycopy(arr1, 0, arr2, 0, arr1.length);
for(int i = 0; i < arr2.length; i++)
System.out.print(arr2[i] + " ");
System.out.println();
}
}
### 5.2.2 Arrays 類別
對陣列的一些基本操作,像是排序、搜尋與比較等動作是很常見的,在 Java 中提供了 Arrays 類別可以協助您作這幾個動作,Arrays 類別位於 java.util 套件中,它提供了幾個方法可以直接呼叫使用。 表 5.2 Arrays 類別提供的幾個方法說明 名稱 說明
sort() 幫助您對指定的陣列排序,所使用的是快速排序法
binarySearch() 讓您對已排序的陣列進行二元搜尋,如果找到指定的值就傳回該值所在的索引,否則就傳回負值
fill() 當您配置一個陣列之後,會依資料型態來給定預設值,例如整數陣列就初始為 0,您可以使用Arrays.fill()方法來將所有的元素設定為指定的值
equals() 比較兩個陣列中的元素值是否全部相等,如果是將傳回true,否則傳回 false
Arrays 類別新增的兩個方法說明
名稱 說明
deepEquals() 對陣列作深層比較,簡單的說,您可以對二維仍至三維以上的陣列進行比較是否相等
deepToString() 將陣列值作深層輸出,簡單的說,您可以對二維仍至三維以上的陣列輸出其字串值
範例 5.15 是個簡單示範,它對三個二維陣列進行深層比較與深層輸出。 範例 5.15 NewArraysDemo.java
import java.util.Arrays;
public class NewArraysDemo { public static void main(String args[]) { int[][] arr1 = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; int[][] arr2 = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; int[][] arr3 = {{0, 1, 3}, {4, 6, 4}, {7, 8, 9}};
System.out.println("arr1 內容等於 arr2 ? " +
Arrays.deepEquals(arr1, arr2));
System.out.println("arr1 內容等於 arr3 ? " +
Arrays.deepEquals(arr1, arr3));
System.out.println("arr1 deepToString()\n\t" +
Arrays.deepToString(arr1));
}
}
執行結果:
arr1 內容等於 arr2 ? true arr1 內容等於 arr3 ? false arr1 deepToString() [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
foreach 與陣列
J2SE 5.0 新增了 foreach 的語法,又稱加強的 for 迴圈(Enhanced for Loop),其應用的對象之一是在陣列的循序存取上,foreach 語法如下:
for(type element : array) { System.out.println(element).... }
直接以實例的方式來說明會更容易瞭解這個語法如何使用,在 J2SE 5.0 之前您可以使用以下的方式來循序存取陣列中的元素:
int[] arr = {1, 2, 3, 4, 5}; for(int i = 0; i < arr.length; i++){ System.out.println(arr[i]); }
在 J2SE 5.0 中可以使用新的 foreach 語法這麼寫:
int[] arr = {1, 2, 3, 4, 5}; for(int element : arr){ System.out.println(element); }
每一次從 arr 中取出的元素,會自動設定給 element,您不用自行判斷是否超出了陣列的長度,注意 element 的型態必須與陣列元素的元素的型態相同。