Java中基本的經常使用的集合類,主要包含:編程
這幾種類型的繼承關係如圖: 圖片引自——Collection 和 Map的繼承體系
其中 List、Queue 和 Set 繼承自 Collection 接口,這三種集合的結構都比較簡單,都是普通的元素的集合,而 Map 相對複雜一點,是鍵值對(key-value)的結構。數組
Iterable 接口是 Collection 接口的「超類」,也就是說 Iterable 接口是 List、Set、Queue 這類簡單集合的頂級接口,看下 Iterable 接口有些啥:
Iterable 接口包含三個方法:app
Iterable 接口的 forEach() 和 spliterator() 方法是用 default 關鍵字修飾的,接口裏包含了方法的默認實現。函數式編程
Iterator 也是一個接口,用於集合的遍歷:
函數
Collection 接口包含了集合的基本的增刪查操做。既然是集合,那麼如下基本方法是很是必要的:.net
爲了增長可用性,又加多了幾個方法:設計
isEmpty() 判空,少寫幾句 "collection.size==0";3d
containsAll() 判斷是否包含另外一個集合裏的全部元素;對象
toArray()、toArray(T[]) 把集合轉化爲數組;blog
clear() 清除全部元素;
removeIf() 條件刪除;
stream() 流操做;
removeAll() 取補集,把另外一個集合也包含的元素去除;
addAll() 把另外一個集合的元素添加進來,至關於取並集;
retainAll() 取交集,把另外一個集合也包含的元素保留下來;
stream()、parrallelStream() 流操做、並行流操做。
List 中文譯做「清單、列表」,List 是有序的,是按照必定的順序來存儲元素的,既然是有序的集合,就應該能夠經過「遊標」來進行訪問,所以,List 在 Collection 的基礎上添加了經過遊標訪問元素,或經過元素獲取遊標的方法:
get(int);
add(int, E);
remove(int);
indexOf(Object);
subList(int, int);經過遊標截取子序列。
lastIndexOf(Object); 由於 List 是有序的,因此能夠經過「遊標」肯定惟一的元素,所以 List 是容許集合中包含相同(相等)的多個元素的,lastIndexOf(Object) 能夠用來在集合包含多個相同元素時,獲取該元素最後出現的位置。
除此以外,List 還加上了 Collection 沒有的「改」操做,實現了集合的「增刪查改」:
由於 List 是有序集合,所以給 List 加上排序操做是可取的:
在List接口中有一個 「ListIerator()」的方法,該方法返回一個 ListIterator 對象。
ListIterator 繼承了 Iterator 接口,提供了 previous 操做,以及與遊標相關的 nextIndex() 和 previousIndex()。
Queue(隊列)是一種特殊的線性表,有的時候咱們會由於業務需求,須要一個「規定容量的Queue」,這時,若是隊列滿了卻又要添加元素,該採起怎樣的策略,或者隊列爲空時調用remove該如何處理,這是須要考慮的。Queue 繼承了 Collection,又提供了幾個本身的方法:
offer(E): 隊尾添加元素,與 add 對應,當隊列已滿時返回false, add()方法這種狀況下則會拋出異常。
poll(): 查詢並刪除隊頭元素,與 remove 對應,當隊列爲空時,不會像 remove 那樣拋出異常,而是會返回 null;
element(): 查詢隊頭元素但不刪除,與 peek 對應,隊列爲空時拋出異常。
peek(): 查詢隊頭元素但不刪除,隊列爲空時返回 null;
Set 中文是「一組、一套」的意思。與 List 相比,Set 沒有 List 的「列表、清單」的「列」的語義。Set 是無序的。 Set 與 Collection 在語義以及屬性上最爲接近,Set 繼承了 Collection 的方法,沒有本身新添加的方法,以下所示:
Set 是沒有 List 的 Index 的概念的,List 能夠用 index 惟一肯定一個元素,Map 能夠用 key 惟一肯定一個元素,而 Set 只能靠自身來惟一肯定一個元素,因此 Set 裏面的元素是不能重複的。正由於 Set 這一特性,可使用 Set 給集合去重。
在詞典中,Map 做動詞時是「映射」的意思,key-value,key 映射到 value,能夠經過 key 來獲取 value。Map 和 Iterable 同樣是頂級接口。Map 接口 UML 圖以下:
雖然 Map 是一個頂級接口,可是 Map 和 Set、List、Queue應該是同一層級的接口,它們的方法不少是相似的(功能上)。
基本的增刪查改:
鍵和值的遍歷:
keySet(): 返回 key 的 Set 集合,由於 Map 靠 key 來惟一肯定一個元素,因此 Map 的 key 是不能重複的,天然地,返回的 key 集合是一個 Set;
values(): value 的值不會影響到 Map 的結構,value 是能夠重複的,也是能夠爲 null 的,因此返回的 value 集合應該是一個 Collection;
entrySet: 該方法返回的是 Entry 的 Set 集合, Entry 是 Map 的內部接口,可把其看做一對鍵值對的組合:
其它的方法:
getOrDefault(Object, V): 若是找到 key 爲 object 的鍵值對,則返回其 value, 不然返回本身傳入的 V;
putIfAbsent(K, V): 與 put(K, V) 對應,若是 Map 中已經包含 key 爲 K 的鍵值對或鍵值對的值爲空,put(K, V) 方法會用 V 覆蓋原來的值;而 putIfAbsent(K, V)方法僅返回如今的值,不覆蓋;當 Map 中不存在 key 爲 k 的鍵值對時,put 和 putIfAbsent 都會添加新的元素。 概況說就是若是指定的鍵還沒有映射(映射即關聯,就是 key 和 value 的關聯關係, value 爲 null 也視爲未映射或者說未關聯),將其與給定值相關聯並返回 null ,不然返回當前值。
compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction): 傳一個BiFunction 對象進去實現值的「計算」,此處的「計算」應該是指「操做」,不只僅是指算術上的「計算」。這與 VueJS 的「計算屬性」有點相似。能夠經過該方法實現 Map 數據的轉換、數據的統計。
BiFunction是一個接口,關鍵方法和說明以下圖所示,可配合 lambda 表達式,是函數式編程的思想。
詳情見Java基礎之Java8中Map的compute的使用
computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction): 同 putIfAbsent 同樣,若是 key 未映射( value 爲 null 也視爲未映射),則嘗試使用給定的映射函數計算其值,並將其輸入到此映射中(即設置 value )。
computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction): Present 與 Absent 相反,前者是「存在」的意思,後者是「不在」的意思,顧名思義,該方法是在指定的 key 在 Map 中存在映射時,則嘗試計算給定key 及其當前值的新值。
merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction): merge 其實與 compute 這幾個方法的做用是同樣的,對 key 映射的 value 值進行變換,只是該方法多提供了一個參數 「V value」,至關於用這個參數的 value 和 key 所對應的 value 結合(merge)起來一塊兒變換; 好比想要讓 Map 中存儲的學生的年齡加「1」,使用 computer 的話,能夠在函數裏寫定參數「1」;使用 merge 的話,能夠在調用 merge 方法時把「1」傳進去。這時,若是需求變了,年齡不是加「1」,而是加「2」,使用compute 方法的話須要到方法裏面改這個「1」(magic num);而使用 merge 的話只須要在方法調用時改參數,不用改其它代碼。