# 用Java學資料結構-Array 這是我的資料結構學習筆記的第一篇,所以先來了解一些基礎知識,然後再進入 Array 的部分。 資料結構可以用來處理基礎型別(Primitive Type)和物件(Object)。基礎型別有以下幾種: - Integer - Float - Double - Char - Boolean - String - Byte - Short ## 什麼是 Array - Array 是一種資料結構 - 用來儲存相同型別的元素 - Array 的元素是有序的 - 並且可以透過索引(index)來存取 - Array 的大小是固定的 - 在建立 Array 時,必須指定 Array 的大小 ## Array 的基礎 如果要用城市來記錄 5 個城市的名稱,只用變數的方式,需要定義 5 個變數,如下: ```java String city1 = "台北"; String city2 = "台中"; String city3 = "高雄"; String city4 = "台南"; String city5 = "花蓮"; ``` 但這樣一個一個定義變數,不僅麻煩,而且不容易管理。這時可以使用陣列來解決這個問題。 ```java String[] cities = new String[5]; cities[0] = "台北"; cities[1] = "台中"; cities[2] = "高雄"; cities[3] = "台南"; // 也可以這樣初始化 String[] cities = {"台北", "台中", "高雄", "台南", "花蓮"}; ``` > 陣列的索引是從 0 開始的。 如果你想要取出陣列中的元素,可以使用陣列的索引值,如下: ```java System.out.println(cities[0]); // 台北 System.out.println(cities[1]); // 台中 System.out.println(cities[2]); // 高雄 System.out.println(cities[3]); // 台南 System.out.println(cities[4]); // 花蓮 ``` 如果你想要知道陣列的長度,可以使用 `length` 屬性,如下: ```java System.out.println(cities.length); // 5 ``` 在 JDK 5 之前,如果想要迭代陣列,只能使用 `for` 迴圈,如下: ```java for (int i = 0; i < cities.length; i++) { System.out.println(cities[i]); } ``` 在 JDK 5 之後,Java 提供了 `foreach` 迴圈,可以更簡潔地迭代陣列,如下: ```java for (String city : cities) { System.out.println(city); } ``` ## 多維陣列 多維陣列是指陣列中的元素也是陣列。例如,如果要用城市來記錄 5 個城市的名稱和人口,可以使用二維陣列,如下: ```java String[][] cities = { {"台北", "300 萬"}, {"台中", "200 萬"}, {"高雄", "150 萬"}, {"台南", "100 萬"}, {"花蓮", "50 萬"} }; ``` 如果你想要取出二維陣列中的元素,可以使用兩個索引值,如下: ```java System.out.println(cities[0][0]); // 台北 System.out.println(cities[0][1]); // 300 萬 System.out.println(cities[1]); // {台中, 200 萬} ``` ## 陣列的常用方法與操作 Java 提供了一些常用的方法來操作陣列,如下: - `Arrays.toString()`:將陣列轉換為字串。 - `Arrays.sort()`:將陣列排序,預設是升冪排序。也就是從小到大排序。 - `Arrays.reverse()`:將陣列反轉。也就是將陣列的元素順序反轉。 - `Arrays.binarySearch()`:在排序後的陣列中查找元素。 ```java int[] numbers = {5, 3, 8, 1, 2}; System.out.println(Arrays.toString(numbers)); // [5, 3, 8, 1, 2] Arrays.sort(numbers); System.out.println(Arrays.toString(numbers)); // [1, 2, 3, 5, 8] int index = Arrays.binarySearch(numbers, 3); System.out.println(index); // 2 Arrays.reverse(numbers); System.out.println(Arrays.toString(numbers)); // [8, 5, 3, 2, 1] ``` - `Arrays.fill()`:填充陣列。 ```java int[] numbers = new int[5]; Arrays.fill(numbers, 5); System.out.println(Arrays.toString(numbers)); // [5, 5, 5, 5, 5] ``` - `Arrays.copyOf()`:複製陣列。使用這個複製的方法,他們的參考地址是不一樣的。 ```java int[] numbers1 = {1, 2, 3, 4, 5}; int[] numbers2 = numbers1; int[] numbers3 = Arrays.copyOf(numbers1, numbers1.length); numbers1[0] = 0; System.out.println(Arrays.toString(numbers1)); // [0, 2, 3, 4, 5] System.out.println(Arrays.toString(numbers2)); // [0, 2, 3, 4, 5] System.out.println(Arrays.toString(numbers3)); // [1, 2, 3, 4, 5] System.out.println(numbers1 == numbers2); // true System.out.println(numbers1 == numbers3); // false System.out.println(numbers2 == numbers3); // false ``` > 當你一宣告一個陣列時,實際上是在記憶體中開辟了一塊連續的空間(長度),這個長度是固定的,不能改變。如果你想要改變陣列的長度,只能重新宣告一個新的陣列,然後將舊的陣列複製到新的陣列中。 ## 淺拷貝與深拷貝 在 Java 中,陣列是一種物件,當你將一個陣列賦值給另一個陣列時,實際上是將陣列的參考地址賦值給另一個陣列,這稱為淺拷貝。也就是說,兩個陣列共享同一個記憶體空間,當一個陣列改變時,另一個陣列也會改變。 ```java int[] numbers1 = {1, 2, 3, 4, 5}; int[] numbers2 = numbers1; numbers1[0] = 0; System.out.println(Arrays.toString(numbers1)); // [0, 2, 3, 4, 5] System.out.println(Arrays.toString(numbers2)); // [0, 2, 3, 4, 5] System.out.println(numbers1 == numbers2); // true, 兩個陣列的參考地址是一樣的 ``` 如果你想要深拷貝一個陣列,可以使用 `Arrays.copyOf()` 方法,如下: ```java int[] numbers1 = {1, 2, 3, 4, 5}; int[] numbers2 = Arrays.copyOf(numbers1, numbers1.length); numbers1[0] = 0; System.out.println(Arrays.toString(numbers1)); // [0, 2, 3, 4, 5] System.out.println(Arrays.toString(numbers2)); // [1, 2, 3, 4, 5] System.out.println(numbers1 == numbers2); // false, 兩個陣列的參考地址是不一樣的 ```