1. 程式人生 > >JDK集合框架

JDK集合框架

形式 升序 src list集合 key-value () 算法 其他 set集合

JDK中的集合框架分為兩大類:Collection和Map。Collection以一組Object的形式保存元素,Map以Key-Value對的形式保存元素。

技術分享圖片

上圖列出的類並不完整,只列舉了平時比較常用的類。

基本接口和類型

Collection集合

該接口是Set和List的父接口,主要提供了下面的方法:

boolean add(E e) 往集合中添加新元素。添加成功,返回true,否則返回false
Iterator<E> iterator() 返回Iterator對象,這樣就可以遍歷集合中的所有元素了
boolean contains(Object o) 判斷集合中是否包含指定的元素
int size() 取得集合中元素的個數
void clear() 刪除集合中的所有元素

Collection是最基本的集合接口,一個Collection代表一組Object,即Collection的元素(Elements)。一些Collection允許相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接繼承自Collection的類,JavaSDK提供的類都是繼承自Collection的子接口,如List和Set。

所有實現Collection接口的類都必須提供兩個標準的構造函數:無參數的構造函數用於創建一個空的Collection,有一個Collection參數的構造函數用於創建一個新的Collection,這個新的Collection與傳入的Collection有相同的元素。後一個構造函數允許用戶復制一個Collection。

如何遍歷Collection中的每一個元素?不論Collection的實際類型如何,它都支持一個iterator()的方法,該方法返回一個叠代對象,使用該叠代對象即可逐一訪問Collection中每一個元素。典型的用法如下:

Iterator it = collection.iterator(); // 獲得一個叠代對象
    while(it.hasNext()) {
        Object obj = it.next(); // 得到下一個元素
    }

Set集合

Set是最簡單的集合,集合中的對象不按照特定的方式排序。主要有如下兩個實現:HashSet和TreeSet。

HashSet

HashSet類按照哈希算法來存取集合中的對象,具有很好的存取性能。當HashSet向集合中加入一個對象時,會調用對象的hashCode()方法獲取哈希碼,然後根據這個哈希碼進一步計算出對象在集合中的存放位置。

TreeSet

TreeSet實現了SortedSet接口,可以對集合中的元素排序。如何排序的內容請參考其他文檔,這裏不做詳述。

List集合

List繼承自Collection接口。List是一種有序集合,List中的元素可以根據索引(順序號:元素在集合中處於的位置信息)進行取得/刪除/插入操作。

跟Set集合不同的是,List允許有重復元素。對於滿足e1.equals(e2)條件的e1與e2對象元素,可以同時存在於List集合中。當然,也有List的實現類不允許重復元素的存在。同時,List還提供一個listIterator()方法,返回一個ListIterator接口對象,和Iterator接口相比,ListIterator添加元素的添加,刪除,和設定等方法,還能向前或向後遍歷,具體的方法往下看。List接口的實現類主要有ArrayList,LinkedList,Vector,Stack等。

List算法

Collections提供的多數多態方法都適用於List,在這裏給出這些算法概覽(以後會詳談):

sort 使用合並排序算法排序List,默認為升序排列
shuffle 使用隨機源對指定列表進行置換。(洗牌)
reverse 反轉指定列表中元素的順序
rotate 根據指定的距離輪換指定列表中的元素
swap 交換指定位置上的元素
replaceAll 使用一個值替換列表中出現的所有某一指定值
fill 使用指定元素替換列表中的所有元素
copy 將所有元素從一個列表復制到另一個列表
binarySearch 使用二分搜索法搜索指定列表,以獲得指定對象
indexOfSubList 返回指定列表中第一次出現指定目標列表的起始位置;如果沒有出現這樣的目標,則返回-1
lastIndexOfSubList 返回指定源列表中最後一次出現指定目標列表的起始位置;如果沒有出現這樣的目標,則返回-1

ArrayList

ArrayList實現了可變大小的數組。它允許所有元素,包括null。ArrayList沒有同步。size,isEmpty,get,set方法運行時間為常數。但是add方法開銷為分攤的常數,添加n個元素需要O(n)的時間。其他的方法運行時間為線性。

每個ArrayList實例都有一個容量(Capacity),即用於存儲元素的數組的大小。這個容量可隨著不斷添加新元素而自動增加,但是增長算法並沒有定義。當需要插入大量元素時,在插入前可以調用ensureCapacity方法來增加ArrayList的容量以提高插入效率。

主要方法:

public boolean add(E e) 添加元素
public void add(int index, E element) 在指定位置添加元素
public Iterator<E> iterator() 取得Iterator對象便於遍歷所有元素
public E get(int index) 根據索引獲取指定位置的元素
public E set(int index, E element) 替換掉指定位置的元素

排序方法:

Collections.sort(java.util.List<T>) 對List的元素進行自然排序
Collections.sort(java.util.List<T>, java.util.Comparator<? super T>) 對List中的元素進行自定義排序

LinkedList

LinkedList實現了List接口,允許null元素。此外LinkedList提供額外的get,remove,insert方法在LinkedList的首部或尾部。這些操作使LinkedList可被用作堆棧(stack),隊列(queue)或雙向隊列(deque)。

註意LinkedList沒有同步方法。如果多個線程同時訪問一個List,則必須自己實現訪問同步。一種解決方法是在創建List時構造一個同步的List:

List list = Collections.synchronizedList(new LinkedList(...));

技術分享圖片

Map

  • Map是一種把鍵對象和值對象進行映射的集合,它的每一個元素都包含一對鍵對象和值對象;
  • 向Map添加元素時,必須提供鍵對象和值對象;
  • 從Map中檢索元素時,只要給出鍵對象,就可以返回對應的值對象;
  • 鍵對象不能重復,但值對象可以重復;
  • Map有兩種常見的實現類:HashMap和TreeMap。
V put(K key, V value) 插入元素
V get(Object key) 根據鍵對象獲取值對象
Set<K> keySet() 取得所有鍵對象集合
Collection<V> values() 取得所有值對象集合
Set<Map.Entry<K, V>> entrySet() 取得Map.Entry對象集合,一個Map.Entry代表一個Map中的元素

HashMap

HashMap按照哈希算法來存取鍵對象,有很好的存取性能。和HashSet一樣,要求當兩個鍵對象通過equals()方法比較為true時,這兩個鍵對象的hashCode()方法返回的哈希碼也一樣。

TreeMap

TreeMap實現了SortedMap接口,能對鍵對象進行排序。同TreeSet一樣,TreeMap也支持自然排序和客戶化排序兩種方式。

如果涉及到堆棧,隊列等操作,應該考慮用List,對於需要快速插入,刪除元素,應該使用LinkedList,如果需要快速隨機訪問元素,應該使用ArrayList。盡量返回接口而非實際的類型,如返回List而非ArrayList,這樣如果以後需要將ArrayList換成LinkedList時,客戶端代碼不用改變。這就是針對抽象編程。

JDK集合框架