(虛線框表示接口, 實線框表示普通的類,
空心箭頭表示特定的類實現了接口, 實心箭頭表示某個類可以生成箭頭所指的類對象)
繼承Collection的主要有Set 和 List.
ArrayList 內部實現是用數組, 隨機訪問速度快, 刪除或插入元素速度慢。
LinkedList 內部實現是用鏈表, 隨機訪問速度慢,刪除和插入元素相對較快。
平時最佳的做法可能是將ArrayList作為默認首選,只有你需要使用額外的功能,或者因為經常從表中插入或刪除元素導致程序性能變差的時候,才去選擇LinkedList。
Vector和Stack是過去遺留下來的類,目的只是為了支持老程序,應該在編寫程序時盡量避免使用它們。
Hash
HashSet: 為快速查找而設計,可以認為是基於哈希表的實現。 存入HashSet的元素必須定義hashCode().
LinkedHashSet: 具有HashSet的查詢速度且內部使用鏈表維護元素的順序(按插入的順序或最近最少使用順序)
Tree
TreeSet:保持次序的Set,底層為樹結構(紅黑樹)。使用它可以從Set提取有序的序列。元素必須實現Comparable接口或者在構造TreeSet時傳入Comparator參數。
class Stone { private int volume; public Stone(int volume) { this.volume = volume; } public int getVolume() { return volume; } //...........省略..........// } class Stick implements Comparable{ private int length; public Stick(int length) { this.length = length; } public int getLength() { return length; } @Override public int compareTo(Object o) { Stick st = (Stick)o; return this.getLength() - st.getLength(); } //...........省略..........// } public class MyComparator implements Comparator<Stone>{ @Override public int compare(Stone st1, Stone st2) { return st1.getVolume() - st2.getVolume(); } public static void main(String[] args) { new TreeSet<Stone>(new MyComparator()); //傳入Comparator new TreeSet<Stick>(); //Stick實現了Comparable } }
不管是散列存儲還是樹形存儲,元素都必須實現equals()方法。雖然只有當時被放入HashSet或LinkedHashSet是hashCode()才是必須的,但是,對於良好的編程風格,應該在覆蓋equals()方法的同時也覆蓋hashCode()方法。
SortedSet(接口)保證元素處於排序狀態(按對象的比較函數對元素排序),主要方法有:
Comparator comparator() 返回當前Set使用的Comparator,如果返回空,表示以自然排序(即按元素實現的Comparable中
compareTo()方法排序)。
Object first() 返回容器的第一個元素
Object last() 返回容器的最後一個元素
SortedSet subSet(fromElement, toElement) 生成此Set的子集,范圍從fromElement(包含)到toElement(不包含)
SortedSet headSet(toElement) 生成此Set的子集,由小於toElement的元素組成
SortedSet tailSet(fromElement) 生成此Set的子集,有大於等於fromElement的元素組成
TreeSet實現SortedSet,包括SortedSet的方法。
在Collection接口中執行各種添加和移除的方法都是可選的。也就是說實現Collection接口的類並不需要為這些方法提供有意義的功能實現。這違反了面向對象設計中的規則(無論你選擇如何實現接口,應該保證能夠向該接口發送這些消息)。
可選操作聲明調用某些方法將不會執行有意義的行為,相反,它們會拋出異常。
可選操作是邏輯上的,在實現接口時,還是需要覆蓋接口所謂的可選方法,只不過你不一定要提供有意義的實現,如果不支持該可選方法,可以在該方法出拋出UnsupportedOperationException。
那麼為什麼需要將方法定義為可選呢?
這樣可以防止設計中出現接口過多的情況。如:
現在有下面三種需求(當然可以有更多不同的需求)
不能修改集合內容的容器,
只能添加元素的容器,
只能刪除元素的容器。
那麼現在就需要為上面三種需求各定義一種接口,顯然這樣比起現在的Collection,需要定義更多的接口。這樣會導致接口過多,整個容器類庫將會更加復雜。
注意:UnsupportedOperationException必須是一個罕見的異常。即對大多數類來說,所有操作都應該可以工作,只有在特列中才會有未獲得支持的操作。
HashMap 基於散列表的實現(它取代了HashTable, HashTable是過時的類)。
LinkedHashMap 類似與HashMap, 但是迭代遍歷時,取得“鍵值對”的順序是其插入的順序
或最近最少使用的順序(如果在構造LiskedHashMap傳入參數accessOrder=true)。
比HashMap慢一點,但是在迭代訪問時更快,因為它使用鏈表維護內部的次序。
TreeMap 基於紅黑樹的實現。查看key 或 key-value是,它們會被排序(次序有Comparator或Comparable決定)