原創作品,可以轉載,但是請標注出處地址:http://www.cnblogs.com/V1haoge/p/7229478.html
1、概述
Java的集合類庫很是豐富,囊括了大部分的常見數據結構形式,讓我們可以有目的性的選擇適合當前業務場景和功能場景的集合類。合適的集合框架可以最大程度的提升執行速度和效率。
Java集合類庫中所有的集合類都始於Collection接口和Map接口,前者表示單值集合,后者表示映射集合(雙值集合)。
Java集合框架中的Abstract開頭的抽象類,其實是JDK開發者定義出來用於實現具體集合類的,是面向JDK開發人員的,而不是面向JDK的使用人員。在這些抽象類中一般會將同一類型的集合的一些公共的方法進行實現,避免在具體的集合類中重復的實現,比如contains方法。
2、接口體系
這個結構系統中,我只是簡單的列出了終止於具體集合類型接口的接口繼承結構,從中可以明顯的看出各個接口的位置,下面讓我們來重點介紹一些這些接口,它們的位置及意義。
2.1 Iterable接口
這是一個簡單的接口,實現了該接口的類都可以使用foreach循環迭代,其實foreach底層原理還是Iterator迭代器循環。從上面的接口可以看出,只有單值集合可以使用這種迭代方式。
它內部只擁有一個方法:
1 Iterator<T> iterator();
這個方法用於返回一個基於類型為T的元素集合的迭代器Iterator。
2,2 Iterator接口
這個接口就是迭代器接口,迭代器接口定義了迭代器常用的方法:
1 boolean hasNext(); 2 E next(); 3 void remove();
這三個方法的意義各不相同,但是在使用上卻是互各依賴。
第一個方法hasNext()方法用於驗證迭代器中是否還有元素,如果還有元素則返回true,否則返回false
第二個方法next()方法用於獲取迭代器的下一個元素,如果當前已經到達迭代器末尾,再次調用該方法就會拋出一個NoSuchElementException異常,因此我們可將此方法與之前的hasNext()方法結合使用,先判斷是否擁有下一個元素,然后再獲取元素,這樣如果不存在下一個元素,就不再獲取。
我們可以將next()方法想象成為一個指針,這個指針並不會指向具體的元素,而是指向元素與元素之間的間隙,初始時,該指針位於第一個元素之前的位置,調用next()一次,指針越過第一個元素,指向第一個元素與第二個元素的間隙,而該方法會將越過的元素返回。
第三個方法是remove()方法,用於移除集合中的剛剛被迭代器返回的元素,這個方法的使用是在第二個方法的基礎上進行的,即需要先執行next()方法,然后再執行remove()方法,而且兩個remove方法不能同時執行(即使是第一個元素的移除也要先執行next將第一個元素返回之后才能執行刪除)
2.3 ListIterator接口
ListIterator是Iterator的子接口,在原來的基礎上專門針對序列進行了擴展,其中定義了如下方法:
1 boolean hasNext(); 2 E next(); 3 boolean hasPrevious(); 4 E previous(); 5 int nextIndex(); 6 int previousIndex(); 7 void remove(); 8 void set(E e); 9 void add(E e);
第一個方法:同Iterator
第二個方法:同Iterator
第三個方法:hasPrevious()用於反向遍歷時查詢是否還有剩余元素,作用同第一個方法,只是方向相反
第四個方法:previous()用於獲取反向查詢時的下一個元素,越過下一元素並將該元素返回,作用同第二個方法,方向相反
第五個方法:nextIndex()用於返回下一個位置,如果已到末尾,返回list的長度
第六個方法:previousIndex()用於返回前一個位置,如果處於開始位置,返回-1
第七個方法:remove(),同Iterator
第八個方法:set(E e)用於替換最新返回的元素(可能是next方法返回的也可能是previous方法返回的)
第九個方法:add(E e)用於插入新元素到當前序列的next或者previous將會返回的元素的前方/后方
2.4 Collection接口
Collection接口是單值集合的根接口,其中為這一類型的集合提供了基本的方法定義:
1 int size(); 2 boolean isEmpty(); 3 boolean contains(Object o); 4 Iterator<E> iterator(); 5 Object[] toArray(); 6 <T> T[] toArray(T[] a); 7 boolean add(E e); 8 boolean remove(Object o); 9 boolean containsAll(Collection<?> c); 10 boolean addAll(Collection<? extends E> c); 11 boolean removeAll(Collection<?> c); 12 boolean retainAll(Collection<?> c); 13 void clear(); 14 boolean equals(Object o); 15 int hashCode();
這里列出了Collection接口中定義的所有方法,共有15個:
第一個方法:size()方法用於返回當前集合中元素的數量
第二個方法:isEmpty()用於驗證集合中是否包含元素,若包含元素則返回false,若不包含元素則返回true
第三種方法:contains(Object o)驗證集合中是否包含指定的元素,若包含則返回true,否則返回false
第四個方法:iterator()用於返回基於當前集合的迭代器Iterator
第五個方法:toArray()用於獲取包含當前集合中所有元素的數組,如果集合指定的順序,那么數組的元素將按照這種順序排列,並且這個數組將不再與集合有任何的聯系,任何針對數組的修改都不會影響到集合。
第六個方法:toArray(T[] a)用於獲取包含當前集合中所有元素的數組,與上面的方法不同之處在於,此方法給定一個數組用於存放集合中的元素,若數組足夠大能放得下所有的集合元素,則將數組剩余的位置置null,若數組位數不足以保存所有的集合元素,則重新創建一個數組(這個數組與給定的數組的類型一致)來存放集合元素,第二種情況與上面的第五個方法情況相同。由於此方法給定了一個數組用來存放集合元素,因此效率比上面的略高。
第七個方法:add(E e)用於在集合中添加新的元素,如果集合不允許重復元素且已存在該元素,則返回false,如果集合結構發生了變化則返回true(表示添加到集合中了)
第八個方法:remove(Object o)用於移除集合中的某個元素,集合中刪除元素會帶來集合結構的部分變動。如果集合中包含該元素則返回true
第九個方法:containsAll(Collection<?> c)驗證當前集合中是否包含給定集合中的所有元素,如果包含則返回true,否則返回false
第十個方法:addAll(Collection<? extends E> c)用於將指定集合中的所有元素全部添加到當前集合中去,如果指定集合在添加過程中發生的變化則結果將變得不確定。
第十一個方法:removeAll(Collection<?> c)用於移除當前集合中包含的指定集合中的所有元素,如果當前集合發生的改變則返回true
第十二個方法:retainAll(Collection<?> c)用於保留當前集合中同樣在指定集合中存在的元素,移除所有不包含在指定集合中的元素,若集合發生的變化則返回true
第十三個方法:clear()用於移除當前集合中的所有元素,之后元素為empty
第十四個方法:equals(Object o)用於比較兩個集合對象是否相同
第十五個方法:hashCode()用於返回當前集合對象的hash值
2.5 List接口
List是一種有序集,又稱序列。擁有下標,允許重復的值。其中定義了序列的一些專有的操作方法:
1 E get(int index); 2 E set(int index, E element); 3 void add(int index, E element); 4 E remove(int index); 5 int indexOf(Object o); 6 int lastIndexOf(Object o); 7 ListIterator<E> listIterator(); 8 ListIterator<E> listIterator(int index); 9 List<E> subList(int fromIndex, int toIndex);
第一個方法:get(int index)用於獲取執行下標的元素
第二個方法:set(int index,E element)用於設置執行下標的元素,替換指定位置的元素為給定的元素
第三個方法:add(int index, E element)用於在指定位置插入新元素,其后的元素全部后移一位
第四個方法:remove(int index)移除指定位置的元素,其后的元素全部前移一位
第五個方法:indexOf(Object o)獲取指定元素在序列中的位置(這里指的是第一次出現的位置),如果不存在則返回-1
第六個方法:lastIndexOf(Object o)獲取置頂元素在序列中的位置,方向為從末尾開始(反向)(第一次出現的位置),若不存在返回-1
第七個方法:listIterator()獲取一個基於序列中元素的序列迭代器
第八個方法:listIterator(int index)獲取一個基於序列中元素的序列迭代器,起始位置為指定的位置
第九個方法:subList(int fromIndex, int toIndex)獲取一個子序列,該子序列為截取自當前序列的指定開始位置到指定結束位置的序列段,如果開始位置=結束位置,則該子序列為empty
2.6 Set接口
查看源碼可知Set接口與Collection接口中定義的方法完全一致,Set集合表示的是無序的集合,其中不能有重復的元素。
2.7 Queue接口
Queue是隊列接口,用於保存即將進行處理的元素,除了基本的Collection定義的方法之外,隊列還提供了其他的插入、提取和移除操作。每個方法都存在兩種形式:一種拋出異常(操作出錯時),一種返回一個特殊值(null或者false),后面的這種操作是專門為擁有容量限制的Queue為設計的。
1 boolean add(E e); 2 boolean offer(E e); 3 E remove(); 4 E poll(); 5 E element(); 6 E peek();
第一個方法:add(E e)用於插入指定元素到隊列中,如果不存在容量限制的情況下。如果執行成功返回true,如果執行失敗拋出IllegalStateException異常
第二個方法:offer(E e)用於插入指定元素到隊列中,如果不存在容量限制的情況下。當使用的是容量受限的隊列,使用該方法將優於add方法。如果執行成功返回true,否則返回false。
第三個方法:remove()用於移出隊列頂部的元素,並將移除的元素返回,如果隊列是空的,則會拋出一個NoSuchElementException異常
第四個方法:poll()用於移除隊列頂部的元素,並將移除的元素返回,如果隊列是空的,則會返回null
第五個方法:element(),獲取隊列頂部的元素(並不移除)如果隊列為空,則拋出NoSuchElementException異常
第六個方法:peek()獲取隊列頂部的元素(並不移除)如果隊列為空,則返回null
上面的方法來兩兩對應,分別用於應對兩種不同的情況。
2.8 Map接口
Map是一種鍵值對集合,用於一對一的鍵值存儲,鍵不能重復,值可以重復,一個鍵最多只能找到一個值。
Map擁有三種集合視圖:鍵集合(Set),值集合(Collection)、鍵值映射集合(Set)。
Map集合的順序被定義為其值集(Collection)的迭代器返回的順序。
Map集合的鍵一般使用不可變值,但是值可以使用易變值。因為可變的key可能會影響equals比較。
所有的Map集合的實現類都應該提供兩個構造器:一個是無參構造器用於創建一個空的Map集合,一個是帶Map集合參數的構造器,用於創建一個與給定集合一一對應的新的Map集合。
Map集合中定義的方法如下:
1 int size(); 2 boolean isEmpty(); 3 boolean containsKey(Object key); 4 boolean containsValue(Object value); 5 V get(Object key); 6 V put(K key, V value); 7 V remove(Object key); 8 void putAll(Map<? extends K, ? extends V> m); 9 void clear(); 10 Set<K> keySet(); 11 Collection<V> values(); 12 Set<Map.Entry<K, V>> entrySet(); 13 boolean equals(Object o); 14 int hashCode();
第一個方法:size()用於返回Map集合中鍵值映射的數量
第二個方法:isEmpty()用於驗證集合中是否包含鍵值映射,如果沒有表示集合是空的,返回true,否則返回false,表示集合非空
第三個方法:containsKey(Object key)用於驗證集合中是否包含指定的鍵的映射,如果包含返回true,否則返回false(驗證集合中是否存在與指定的key相同的鍵的映射,如果指定的key是null,則查找null為鍵的映射,否則查找與指定的key一致的鍵的映射)
第四個方法:containsValue(Object value)用於驗證集合中是否存在指定的值的映射(只可以重復,所以此處為至少存在一個),如果至少存在一個則返回true,不存在返回false
第五個方法:get(Object key)用於獲取集合映射中指定鍵的值,如果指定的鍵不存在則返回null,否則返回對應的值。如果這個集合允許null值,那么返回null值就不確定是不存在映射還是存在映射,只是值為null的情況了,這時可以使用第三個方法來進行區分(通過containsKey(Object key)方法來驗證指定的鍵是否存在,如果存在則返回的是正常保存的null值,否則返回的就是指不存在映射)
第六個方法:put(K key, V value)用於將指定的映射保存到集合中去,如果指定的鍵已存在(鍵的存在性判斷是通過containsKey(Object key)方法來判斷的),則執行的是對應值的替換操作。
第七個方法:remove(Object key)用於移除集合中指定鍵的映射,並將移除的映射的值返回,如果不存在指定鍵的映射,則返回null,這對於允許null值的集合來說,又一次產生了歧義,解決方法同上。
第八個方法:putAll(Map<? extends K, ? extends V> m)將指定的map集合中的所有映射拷貝到當前的map集合中去。
第九個方法:clear()用於清空當前的map集合中的所有映射、
第十個方法:keySet()返回map集合中的所有鍵的集合,這是一個set集合,這個集合就是map集合中鍵的映射,因此改變其中任何一項都可以在另一個里面發現這種改變。
第十一個方法:values()用於獲取map集合中包含的映射中的所有值的集合,這個集合是map集合中值的映射,因此改變其中任何一項都可以在另一個里面發現這種改變。
第十二個方法:entrySet()用於獲取map集合中包含的所有映射的集合,這是一個set集合,這個集合就是map集合中映射的映射,因此改變其中任何一項都可以在另一個里面發現這種改變。
2.9 Entry<K,V> 內部接口
該接口是在Map接口內部定義的,專門服務於Map集合,用於表示Map集合中的映射,映射表示的是鍵值對。
1 K getKey(); 2 V getValue(); 3 V setValue(V value); 4 boolean equals(Object o); 5 int hashCode();
第一種方法:getKey()方法用於獲取鍵值映射中的鍵
第二種方法:getvalue()方法用於獲取鍵值映射中的值。
第三種方法:setValue(V value)方法用於重置當前鍵值映射中的值
3、總結
上面的所有接口只是簡單的對集合類型做了區分,划分了四類集合,分別為Queue隊列,List序列,Set集,Map映射集。並對每個類型的集合進行了簡單的方法定義,用於確立此類集合的特點。Java中針對每種集合都有多種實現用於應對不同的場景。