java
陣列(Array)是一組資料的集合,集合裡的每筆資料都會有一個對應的索引值(Index),只要指定索引值就可以取出對應的資料,在程式中經常會使用陣列進行整批資料的存放;在 Java 中,陣列不僅是一組資料群組,也是一個物件,可以透過一些好用的物件方法來做操作,所以比傳統上的一些程式語言的陣列只是一群資料方便許多。
現在要整理全班的 Java 小考成績,您希望寫個小程式,全班共有 10 名學生,每個學生有「姓名」、「學號」、「國文」、「英文」、「數學」等成績。假使用宣告變數的方式,將會需要10 x 50 = 500個變數來儲存成績資料,假使今天班上學生是20名甚至50名呢?光宣告變數就非常麻煩。
Java 提供「陣列」(Array)可以宣告一個以「索引」(Index)作為識別的資料結構,在 Java 中,可以這麼宣告一個陣列並初始陣列內容:
補充
此為陣列簡易宣告方式。
這個程式片段宣告了一個 score 陣列,它的內容包括 1、2、3、4 與 5 這五個元素,要存取陣列時,必須透過索引值來指定存取陣列中的哪個元素,在Java 中陣列的索引是由0開始,也就是說索引 0 的位置儲存 1、索引 1 的位置儲存 2、索引 3 的位置儲存 4,依此類推,如果陣列中的每個值取出並顯示出來,可以使用 for 迴圈,如範例:
執行的結果如下:
在存取陣列元素時,必須注意指定的索引值不可超出陣列範圍,例如上面範例中,陣列最多可以索引到 4,所以不可以存取超過 4 的索引值,否則會發生 ArrayIndexOutOfBoundsException 例外,如果不處理這個例外,程式將會終止。
使用 length 這個陣列物件的屬性成員,在 Java 中陣列是一個物件,而不是單純的資料集合,陣列物件的 length 屬性成員可以取回陣列的長度,也就是陣列中的元素個數。
當宣告一個陣列時,其實就是產生一個陣列物件,在 Java 中物件都是以 new 來配置記憶體空間,陣列一樣,完整的陣列宣告方式如下:
在上面的宣告中,arr 是個 int[] 型態的參考名稱,程式會為 array 配置可以儲存 10 個 int 整數的一維陣列物件,索引為 0 到 9,初始值預設為 0,在 Java 中配置陣列之後,若還沒有指定初值,則依資料型態的不同,會預設有不同的初值,如下表所示:
資料型態 | 初始值 |
---|---|
byte | 0 |
short | 0 |
int | 0 |
long | 0L |
float | 0.0f |
double | 0.0d |
char | \u0000 |
boolean | false |
**範例:**使用配置的語法來宣告陣列,並使用 for 迴圈來設定每個元素的值然後顯示出來:
執行結果:
如果您想要在使用 new 新增陣列時一併指定初始值,則可以如下撰寫:
補充
這個方式不必指定陣列長度,其長度為後面提供的初始值數量。
完整範例:
由於陣列的記憶體空間是使用 new 配置而來,表示也可以使用動態的方式來宣告陣列長度,而不用在程式中事先決定陣列大小,例如:
執行結果:
解說:
先宣告一個陣列參考名稱 score,使用 float[] score 表示 score 名稱將參考至一個元素為 float 的一維陣列物件,在使用者輸入指定長度後,再使用這個長度來配置陣列物件,並將這個陣列物件指定給 score 名稱來參考。
補充
陣列的索引值由 0 開始表示的是:所指定的陣列元素相對於陣列第一個元素記憶體位置的位移量(Offset)。索引為 0 表示位移量為 0,所以就是指第一個元素,而索引 9 就是指相對於第一個元素的位移量為 9。
一維陣列使用「名稱」與「一個索引」來指定存取陣列中的元素,二維陣列使用「名稱」與「兩個索引」來指定存取陣列中的元素,其宣告方式與一維陣列類似:
從上面這個程式片段來看,可以看出二維陣列的索引方式,宣告了 2 列(Row)3 行(Column)的陣列,使用 { } 與適當的斷行可以指定陣列初值。
二維陣列的存取:
執行結果:
陣列值 arr[i][j]
表示指定的是第 i 列第 j 行的值。在使用二維陣列物件時,注意 length 所代表的長度,陣列名稱後直接加上 length(如 arr.length
),所指的是有幾列(Row);指定索引後加上 length(如 arr[0].length
),指的是該列所擁有的元素,也就是行(Column)數目。
範例:
透過將陣列元素指定給變數來存取二維陣列
如果在使用 new 配置二維陣列後想要一併指定初值,則可以如下撰寫:
陣列的長度並不一定要全部長度都相同,一個二維陣列中,可以每個元素的長度都是不同的陣列,列如:
這個例子中,陣列第一列的長度是3,而第二列的長度是 5,執行結果如下:
宣告三維以上的陣列,如果要同時宣告初始元素值,可以使用以下的簡便語法:
如果要動態宣告三維陣列,就使用以下的語法:
提示
三維以上的更多維陣列之宣告,在Java中雖然可行,但並不建議使用,使用多維陣列會讓元素索引的指定更加困難,此時適當的將資料加以分割,或是使用其它的資料結構來解決,會比直接宣告多維陣列來得實在。
藉由對陣列物件的進一步探討,您可以稍微瞭解 Java 對物件處理的一些作法,首先來看看一維陣列的參考名稱之宣告:
在這個宣告中,arr 表示一個可以參考至 int 一維陣列物件的參考名稱,但是目前您將這個名稱參考至 null,表示這個名稱參考還沒有參考至實際的物件,在 Java 中,'=' 運算用於基本資料型態時,是將值複製給變數,但當用於物件時,則是將物件指定給參考名稱來參考,您也可以將同一個物件指定給兩個參考名稱,當物件的值藉由其中一個參考名稱進行操作而變更時,另一個參考名稱所參考到的值也會更動,例如:
執行結果:
在這個範例中,藉由 tmp1 名稱改變了索引 2 的元素值,由於 tmp2 也參考至同一陣列物件,所以 tmp2 索引 2 元素值也被跟著改變;有三個參考名稱參考至同一個陣列物件,也就是 arr1、tmp1 與 tmp2。
所以,如果取出 arr1 索引 2 的元素,元素值也會是 9。
在宣告 int[] arr 之後,arr 是一個一維陣列物件的參考名稱,所以它可以參考至任何長度的一維陣列物件,例如:
tmp 可以參考至擁有5個元素的一維陣列,也可以參考至擁有 3 個元素的一維陣列,執行結果如下:
在 Java 中陣列是一個物件,使用 '=' 指定時,是將物件==「指定給陣列名稱來參考,而不是將陣列進行複製」==,如果想將整個陣列的值複製給另一個陣列的話,可以使用迴圈,將整個陣列的元素值走訪一遍,並指定給另一個陣列相對應的索引位置,例如:
執行結果:
另一個進行陣列複製的方法是使用 System 類別所提供的 arraycopy() 方法,其語法如下:
例如:
補充
或是使用 Arrays 類別的copyOf() 方法
對陣列的一些基本操作,像是排序、搜尋與比較等動作是很常見的,在 Java 中提供了 Arrays 類別可以協助您作這幾個動作,Arrays 類別位於 java.util 套件中,它提供了幾個方法可以直接呼叫使用。
名稱 | 說明 |
---|---|
copyOf() | 複製陣列內容 |
sort() | 幫助您對指定的陣列排序,所使用的是快速排序法 |
binarySearch() | 讓您對已排序的陣列進行二元搜尋,如果找到指定的值就傳回該值所在的索引,否則就傳回負值 |
fill() | 當您配置一個陣列之後,會依資料型態來給定預設值,例如整數陣列就初始為 0,您可以使用Arrays.fill()方法來將所有的元素設定為指定的值 |
equals() | 比較兩個陣列中的元素值是否全部相等,如果是將傳回true,否則傳回 false |
使用 Arrays 來進行陣列的排序與搜尋:
執行結果:
使用 Arrays 來進行陣列的填充與比較:
執行結果:
請注意到,不可以用 ==
來比較兩個陣列的元素值是否相等,==
使用於物件比對時,是用來測試兩個物件名稱是否參考至同一個物件,也就是測試兩個名稱是不是綁定至同一個物件,例如:
雖然 arr1 與 arr2 中的元素值是相同的,但實際上 arr1 與 arr2 是參考至不同的兩個陣列物件,將 arr1 指定給 tmp 來參考,由於 tmp 與 arr1 是參考同一陣列物件,所以進行 arr1==tmp
比較時會顯示 true,而 tmp 與 arr2 是參考至不同陣列物件,所以進行 arr2==tmp
比較時會顯示 false,執行結果如下:
名稱 | 說明 |
---|---|
deepEquals() | 對陣列作深層比較,簡單的說,您可以對二維仍至三維以上的陣列進行比較是否相等 |
deepToString() | 將陣列值作深層輸出,簡單的說,您可以對二維仍至三維以上的陣列輸出其字串值 |
對三個二維陣列進行深層比較與深層輸出:
執行結果:
foreach也是迴圈的一種,又稱加強的 for 迴圈(Enhanced for Loop),其應用的對象之一是在陣列的循序存取上,語法如下:
原本使用以下的方式來循序存取陣列中的元素:
改使foreach語法:
每一次從 arr 中取出的元素,會自動設定給 element,不需判斷是否超出了陣列的長度,注意 element 的型態必須與陣列元素的元素的型態相同。
如果是物件的話,作法也是類似,例如存取字串陣列的話,可以如下:
二維陣列也是相同作法:
三維以上的陣列使用 foreach 的方式來存取也可以依此類推。
由字元所組成的一串文字符號被稱之為「字串」,例如 "Hello" 這個字串就是由 'H'、'e'、'l'、'l'、'o' 這五個字元所組成,在某些程式語言中,字串是以字元陣列的方式存在。
在 Java 中字串不僅僅是字元陣列,而是 String 類別的一個實體,在Java因為String使用的頻率很高,所以可以不需要使用標準物件的建立方式,而是可以像基本型態一樣來宣告一個字串,例如:
注意字串的直接指定必須使用分號 "" 來包圍著文字,字串的每個字元是使用 Unicode 字元來建構,在建構一個字串物件之後,可以直接在標準輸出串流(out)中指定字串物件的參考名稱來輸出字串。
字串的串接在 Java 中可以直接使用 '+' 運算子,'+' 本來是加法運算子,但使用在字串上會被重新定義(Override)為字串的串接,例如:
這一段程式碼會在文字模式上顯示 "哈囉!Aaron Ho!"。 字串在 Java 中以 String 類別的一個實例存在,所以每個字串物件本身會擁有幾個可操作的方法。
String 物件常用方法
方法 | 說明 |
---|---|
length() | 取得字串的字元長度 |
equals() | 判斷原字串中的字元是否相等於指定字串中的字元 |
toLowerCase() | 將字串中的英文字元轉為小寫 |
toUpperCase() | 將字串中的英文字元轉為大寫 |
示範了以上的幾個字串操作方法的使用:
執行結果:
如果要將輸入的字串轉換為整數、浮點數等資料型態,可以使用下表各類別所提供的各個靜態(static)解析方法:
方法 | 說明 |
---|---|
Byte.parseByte(字串) | 將字串剖析為位元 |
Short.parseShort(字串) | 將字串剖析為short整數 |
Integer.parseInt(字串) | 將字串剖析為int整數 |
Long.parseLong(字串) | 將字串剖析為long整數 |
Float.parseFloat(字串) | 將字串剖析為float浮點數 |
Double.parseDouble(字串) | 將字串剖析為double浮點數 |
注意如果指定的字串無法剖析為指定的資料型態數值,則會發生 NumberFormatException
例外。
宣告字串時,都是以這樣的樣子來宣告:
這樣的宣告方式看來像是基本資料型態宣告,但事實上 String 並不是 Java 的基本資料型態,String 是 java.lang 套件下所提供的類別,如果以正常配置物件的觀念來宣告字串,應該為:
取得字串中的字元之方法
方法 | 說明 |
---|---|
char charAt(int index) | 傳回指定索引處的字元 |
int indexOf(int ch) | 傳回指定字元第一個找到的索引位置 |
int indexOf(String str) | 傳回指定字串第一個找到的索引位置 |
int lastIndexOf(int ch) | 傳回指定字元最後一個找到的索引位置 |
String substring(int beginIndex) | 取出指定索引處至字串尾端的子字串 |
String substring(int beginIndex, int endIndex) | 取出指定索引範圍子字串 |
char[] toCharArray() | 將字串轉換為字元陣列 |
範例:
執行結果:
在初始化字串物件時,除了直接在 '=' 後使用 "" 來指定字串常數之外,也可以使用字元陣列來初始化,例如使用字元陣列 name,建構出一個內容為 "aaron" 的字串:
使用 endsWith() 方法可以判斷字串是不是以指定的文字作為結束,這個常用在過濾檔案名稱,例如:
執行結果:
補充
在宣告字串一併指定字串值時,如果字串長度過長,可以分作兩行來寫,這樣比較容易閱讀,例如:
使用字串有一個非常重要的觀念必須知道,一個字串物件一旦被配置,它的內容就是固定不可變的(immutable),例如下面這個宣告:
這個宣告會配置一個長度為 8、內容為 "Aaron Ho" 的字串物件,誰都無法改變這個字串物件的內容;下面的程式並不是改變一個字串物件的內容:
事實上在這個程式片段中會有兩個字串物件,一個是 "Hello" 字串物件,長度為 5,一個是 "Java" 字串物件,長度為 4,兩個是不同的字串物件。
在 Java 中,使用 '=' 將一個字串物件指定給一個參考名稱,其意義為==「改變該名稱所參考的物件」==,原來被參考的字串物件若沒有其它名稱來參考它,就會在適當的時機被 Java 的「垃圾回收」 (Garbage collection)機制回收,在 Java 中,程式設計人員通常不用關心無用物件的資源釋放問題,Java 會檢查物件是否不再被參考,如果沒有被任何名稱參考的物件將會被回收。
在 Java 執行時會維護一個String池(Pool),對於一些可以共享的字串物件,會先在 String 池中查找是否存在相同的 String 內容(字元相同),如果有就直接傳回,而不是直接創造一個新的 String 物件,以減少記憶體的耗用,在程式中使用下面的方式來宣告,則實際上是指向同一個字串物件:
當直接在程式中使用 "" 來包括一個字串時,該字串就會在 String 池中。
如果 ==
被使用於兩個參考名稱時,它是用於比較兩個參考名稱是否參考至同一物件,所以str1==str2 比較時,程式的執行結果會顯示 true。
==
在 Java 中被用來比較兩個參考名稱是否參考至同一物件,所以==「不可以用 ==
來比較兩個字串的字元內容是否相同」==,例如:
雖然兩個字串物件的字元值完全相同,但實際上在這個程式片段中,因為產生了兩個 String 的實例,str1 與 str2 分別參考至不同的實例,所以使用 '==' 比較時結果會顯示 false,如果要比較兩個字串物件的字元值是否相同,需要使用 equals() 方法,例如:
一個常見的問題是:上面的程式片段產生了幾個 String 的實例?很多人會回答 2 個,但答案是 3 個,因為 "aaron" 就是一個,它存在於字串池中,而您又使用 new 建構出兩個 String 物件,分別由 str1 與 str2 參考,所以總共會有 3 個 String 實例。
一個 String 物件的長度是固定的,您不能改變它的內容,或者是附加新的字元至 String 物件中,您也許會使用 '+' 來串接字串以達到附加新字元或字串的目的,但 '+' 會產生一個新的 String 實例,如果程式對這種附加字串的需求很頻繁,並不建議使用 '+' 來進行字串的串接,在物件導向程式設計中,最好是能重複運用已生成的物件,物件的生成需要記憶體空間與時間,不斷的產生 String 實例是一件沒有效率的行為。
使用 StringBuilder 會讓程式的效率大大提昇,例如:
首先使用 '+' 來串接字串,再使用 System.currentTimeMillis() 取得 for 迴圈執行前、後的系統時間,如此就可以得知 for 迴圈執行了多久,例如:
使用 StringBuilder 最後若要輸出字串結果,可以呼叫toString() 方法;可以使用 length() 方法得知目前物件中的字元長度,而 capacity() 可傳回該物件目前可容納的字元容量,另外 StringBuilder 還有像是 insert() 方法可以將字元插入指定的位置,如果該位置以後有字元,則將所有的字元往後移;deleteChar() 方法可以刪除指定位置的字元,而 reverse() 方法可以反轉字串。
補充
還有另一個StringBuffer與StringBuilder 被設計具有相同的操作介面,在單機非「多執行緒」(Multithread)的情況下使用 StringBuilder 會有較好的效率,因為 StringBuilder 沒有處理「同步」(Synchronized)問題;StringBuffer 則會處理同步問題,如果StringBuilder 會在多執行緒下被操作,則要改用 StringBuffer,讓物件自行管理同步問題。
在文字模式下執行程式時,通常可以連帶指定一些引數給程式。
在文字模式下啟動一個 Java 程式時,也可以一併指定引數,以讓程式進行相對應的功能,也就是輸入命令列引數(Command line argument)給程式,在您撰寫主程式時,會在 main() 的參數列撰寫 String[] args,目的就是用來接受一個字串陣列,只要取得 args 中的元素值,就可以取出 Java 程式運行時被指定的引數,例如:
args 索引 0 的值是從程式名稱後第一個引數開始,以空白為區隔,依序地儲存在 args 陣列中,執行的方式與結果如下頁:
也可使用foreach來取得每個引數:
將字串依所設定的條件予以分離是很常見的操作,例如指令的分離、文字檔案的資料讀出等,以後者而言,在文字檔案中儲存以下的資料時,在讀入檔案後,將可以使用 String 的 split() 來協助每一個資料分離。
例如:
執行結果:
split() 依您所設定的分隔設定,將字串分為數個子字串並以 String 陣列傳回。
在程式運行的過程中,很多時候您需要將物件暫時儲存在一個容器中統一管理,之後需要時再將物件取出,要使用什麼樣的容器依設計需求而定:
java.util.ArrayList 類別實作了 java.util.List 介面,所以要先認識一下 List 介面,List 介面是 java.util.Collection 介面的子介面,而 Collection 介面則是 java.lang.Iterable 的子介面,Iterable 介面要求實作一個 iterator() 方法。
package java.lang;
import java.util.Iterator;
public interface Iterable<T> {
Iterator<T> iterator();
}
從 J2SE 5.0 開始增加了泛型設計的新功能,所以像 Iterable、Collection 相關介面與其實作類別,都使用泛型的功能重新改寫了。
Iterable 介面要求實作它的類別傳回一個實作 java.util.Iterator 介面的物件,事實上您在 Java SE 的 API 中找不到任何實作 Iterator 的類別,因為 Iterator 會根據實際的容器資料結構來迭代元素,而容器的資料結構實作方式對外界是隱藏的,使用者不用知道這個結構,只需要知道 Iterator 的操作方法,就可以取出元素,Iterator 介面的定義如下:
package java.util;
public interface Iterator<E> {
boolean hasNext();
E next();
void remove();
}
Collection 介面繼承了 Iterator 介面,定義了加入元素、移除元素、元素長度等方法,
package java.util;
public interface Collection<E> extends Iterable<E> {
int size();
boolean isEmpty();
boolean contains(Object o);
Iterator<E> iterator();
<T> T[] toArray(T[] a);
boolean add(E o);
boolean remove(Object o);
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c);
boolean removeAll(Collection<?> c);
boolean retainAll(Collection<?> c);
void clear();
boolean equals(Object o);
int hashCode();
}
Collection 在移除元素及取得元素上的定義是比較通用,List 介面則又增加了根據索引取得物件的方法,這說明了 List 資料結構的特性,每個加入 List 中的元素是循序加入的,並可指定索引來存取元素(以下原始碼只是節錄部份)。
package java.util;
public interface List<E> extends Collection<E> {
....
boolean addAll(int index, Collection<? extends E> c);
E get(int index);
E set(int index, E element);
void add(int index, E element);
E remove(int index);
int indexOf(Object o);
int lastIndexOf(Object o);
List<E> subList(int fromIndex, int toIndex);
....
}
List 資料結構的特性是,每個加入 List 中的元素是循序加入的,並可指定索引來存取元素,List 可以使用陣列(Array)或是鏈結串列(Linked List)來實作這個特性,前者在 Java SE 中的實作就是 java.util.ArrayList,後者就是 java.util.LinkedList,對於循序加入與存取,使用 ArrayList 的效率比較好,對於經常變動元素排列順序的需求,使用 LinkedList 會比較好。
ArrayList 實作了 List 介面,ArrayList 使用陣列結構實作 List 資料結構,陣列的特性是可以使用索引來快速指定物件的位置,所以對於快速的隨機取得物件來說,使用 ArrayList 可以得到較好的效能,但由於使用陣列實作,若要從中間作移除或插入物件的動作,會需要搬動後段的陣列元素以重新調整索引順序,所以速度上就會慢的多。
先來看看一個使用 ArrayList 的例子,例如:
Java的泛型(Generic)的功能,使用物件容器時可以宣告將儲存的物件型態,物件在存入容器會被限定為宣告的型態,編譯器在編譯時期會協助進行型態檢查,而取出物件時也不至於失去原來的型態資訊,這可以避免型態轉換時的問題。
使用 add() 方法可以將一個物件加入 ArrayList中,使用 size() 方法可以傳回目前的 ArrayList 的長度,使用 get() 可以傳回指定索引處的物件,使用 toArray() 可以將 ArrayList 中的物件轉換為物件陣列,執行結果如下:
輸入名稱(使用quit結束)
# Aaron
# Apple
# Andy
# quit
顯示輸入: Aaron Apple Andy
可以使用 get() 方法指定索引值取出物件,如果要循序取出容器中所有的物件,則可以使用 Iterator:
iterator() 方法會傳回一個 Iterator 物件,這個物件提供遍訪容器元素的方法,hasNext() 方法測試 Iterator 中是否還有物件,如果有的話,可以使用 next() 方法取出。
另外,也可以使用foreach來取得每個元素:
java.util.HashSet 實作了 java.util.Set 介面,Set 介面一樣繼承了 Collection 介面,List 容器中的物件允許重複,但Set 容器中的物件都是唯一的,Set 容器有自己的一套排序規則,所以無法確保元素的順序跟存入的順序一樣。
HashSet 的排序規則是利用湊雜(Hash),所以加入 HashSet 容器的物件還必須重新定義 hashCode() 方法,HashSet 根據湊雜碼來確定物件於容器中儲存的位置,也可以根據雜湊碼來快速的找到容器中的物件。
在比較兩個加入 HashSet 容器中的物件是否相同時,會先比較 hashCode() 方法傳回的值是否相同,如果相同,則再使用 equals() 方法比較,如果兩者都相同,則視為相同的物件。
提示
在定義類別時,最好總是重新定義 equals() 與 hashCode() 方法,以符合 Java 的設計規範。
HashSet範例:
可以看到,即使重複加入了 "Aaron Ho" 字串,HashSet 中仍只有一個 "Aaron Ho" 字串物件,這是 Set 的特性,另一個要注意的是,迭代 HashSet 中所有的值時,其順序與加入容器的順序可能不相同,迭代所有值時的順序是 HashSet 排序過後的順序,執行結果如下:
bush momor Aaron Ho
momor Aaron Ho
實作 java.util.Map 介面的物件會將「鍵」(Key)映射至「值」(Value),「值」指的是要存入 Map 容器的物件。在將物件存入 Map 物件時,需要同時給定一個「鍵」,要取回物件時可以指定鍵,如此就可以取得與鍵對應的物件「值」,Map 中的每一個鍵都是唯一的,不能有重複的鍵,Map也擁有自己的排序機制。
Map 的特性即「鍵-值」(Key-Value)匹配,簡單的說,可以將實作 Map 介面的容器物件當作一個有很多房間的房子,每個房間的門有唯一的鑰匙(Key),將物件儲存至房間中時,要順便擁有一把鑰匙,下次要取回物件時,就是根據這把鑰匙取回物件。
java.util.HashMap 實作了 Map 介面,HashMap 在內部實作使用雜湊(Hash),用來在很快的時間內可以找到「鍵-值」(Key-Value)匹配的資料,例如:
在範例中宣告 Map 型態與新增 Map 實例時,指定了「鍵-值」所要使用的型態,在範例中都是宣告為 String 型態,也就是要以 String 物件作為「鍵」,而存入的「值」也要是 String 物件,使用 Map 的 put() 方法將物件存入時,必須同時指定「鍵」和「值」,而要取回物件時,則使用 get() 方法並指定「鍵」,傳回的會是對應於鍵的「值」,程式的執行結果如下:
Aaron Ho 的訊息
Apple Chen 的訊息
可以使用 values() 方法返回一個實作 Collection 的物件,當中包括所有的「值」物件,如果需要一次迭代 Map 中所有的物件,這會很有用,例如:
結果如下:
momor 的訊息
Apple Chen 的訊息
Aaron Ho 的訊息
momor 的訊息
Apple Chen 的訊息
Aaron Ho 的訊息
如果想要在迭代所有的物件時,依照插入的順序來排列,則可以使用 java.util.LinkedHashMap,它是 HashMap 的子類別,在使用 values() 所返回的 Collection 物件,其內含物件之順序即為當初加入物件之順序,例如:
執行結果: