chapter6
文章目錄
- 1.集合概述
- 1.1.基本概念
- 1.2.集合分類
- 2.Collection接口
- 3.List接口
- 3.1. List接口簡介
- 3.1.1.定義
- 3.1.2.特點
- 3.1.3.常用方法
- 3.2. ArrayList類
- 3.2.1.特點
- 3.2.2.語法
- 3.3. LinkedList類
- 3.3.1.特點
- 3.3.2.底層原理
- 3.3.3.特有方法
- 3.3.4.語法
- 4.Collection集合遍歷
- 4.1. Iterator遍歷集合
- 4.1.1.工作原理
- 4.1.2.實現
- 4.1.3.注意
- 4.2. foreach遍歷集合
- 4.3. JDK8 ---- foreach遍歷集合
- 4.4.forEachRemaining
- 5.Set接口
- 5.1. Set接口簡介
- 5.1.1.特點
- 5.1.2.分類
- 5.2. HashSet類
- 5.2.1.特點
- 5.2.2.存儲原理
- 5.3. TreeSet類
- 5.3.1.特點
- 5.3.2.存儲原理
- 5.3.3.特有方法
- 5.3.4.排序
- 5.3.4.1.基本概念
- 5.3.4.2.分類
- 5.3.4.2.主要區別
- 5.3.4.2.實現
- 6.Map接口
- 6.1. Map接口簡介
- 6.1.1.特點
- 6.1.2.常用方法
- 6.2. HashMap類
- 6.2.1.特點
- 6.2.2.內部結構
- 6.2.3.存儲原理
- 6.2.4.注意
- 6.2.4.LinkedHashMap
- 6.3. Map集合遍歷
- 6.3.1.Iterator迭代器
- 6.3.1.1.keySet()方法
- 6.3.1.2.entrySet()方法
- 6.3.2.JDK8提供的forEach
- 6.3.3.值遍歷—values()方法
- 6.4. TreeMap集合
- 6.5. Properties集合
- 7.泛型
- 7.1.why
- 7.2.語法
- 8.常用工具類
- 8.1. Collections工具類
- 8.1.1.添加、排序常用方法
- 8.1.2.查找、替換常用方法
- 8.2. Arrays工具類
- 9.JDK8 ---- 聚合操作
- 9.1. 聚合操作簡介
- 9.2. 創建Stream流對象
- 9.3. Stream流的常用方法
- 9.4. Parallel Stream (并行流)
- 9.4.1.串并流對比
- 9.4.2.并行流創建
- 9.4.3.注意
- 9.4.3.注意
1.集合概述
1.1.基本概念
-
集合可以存儲任意類型的對象,并且長度可變
-
集合對象可以是任意的數據類型,并且長度可變
1.2.集合分類
| 單列集合根接口,用于存儲一系列符合某種規則的元素 | 雙列集合根接口,用于存儲具有鍵(Key)、值(Value)映射關系的元素 |
| Collection集合有兩個重要的子接口,分別是List和Set | Map集合中每個元素都包含一對鍵值,并且Key唯一,在使用Map集合時通過指定的Key找到對應的· |
| List集合的特點是元素有序、可重復。該接口的主要實現類有ArrayList和LinkedList | Map接口的主要實現類有HashMap和TreeMap |
| Set集合的特點是元素無序并且不可重復。該接口的主要實現類有HashSet和TreeSet |
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-PkC8S47W-1634995158221)(https://i.loli.net/2021/10/22/TO8apPtlNEo6Lvs.png)]
2.Collection接口
| boolean add(Object o) | 向集合中添加一個元素 |
| boolean addAll(Collection c) | 將指定集合c中的所有元素添加到該集合中 |
| void clear() | 刪除該集合中的所有元素 |
| boolean remove(Object o) | 刪除該集合中指定的元素 |
| boolean removeAll(Collection c) | 刪除該集合中包含指定集合c中的所有元素 |
| boolean isEmpty() | 判斷該集合是否為空 |
| boolean contains(Object o) | 判斷該集合中是否包含某個元素 |
| boolean containsAll(Collection c) | 判斷該集合中是否包含指定集合c中的所有元素 |
| Iterator iterator() | 返回在該集合的元素上進行迭代的迭代器(Iterator),用于遍歷該集合所有元素 |
| int size() | 獲取該集合元素個數 |
| Stream stream() | 將集合源轉換為有序元素的流對象(JDK 8新方法) |
3.List接口
3.1. List接口簡介
3.1.1.定義
- List接口繼承自Collection接口,是單列集合的一個重要分支,習慣性的會將實現了List接口的對象稱為List集合
3.1.2.特點
- List集合中允許出現重復元素,所有的元素是以一種線性方式進行存儲的,在程序中可以通過索引(類似于數組中的元素角標)來訪問集合中的元素
- 元素有序,存入順序和取出順序一致
3.1.3.常用方法
| void add(int index,Object element) | 將元素element插入在List集合的指定索引位置 |
| boolean addAll(int index,Collection c) | 將集合c包含的所有元素插入到List集合的指定索引位置 |
| Object get(int index) | 返回集合索引index處的元素 |
| Object remove(int index) | 刪除index索引處的元素 |
| Object set(int index, Object element) | 將索引index處元素替換成element元素,并將替換后的元素返回 |
| int indexOf(Object o) | 返回對象o在List集合中首次出現的位置索引 |
| int lastIndexOf(Object o) | 返回對象o在List集合中最后一次出現的位置索引 |
| List subList(int fromIndex, int toIndex) | 返回從索引fromIndex(包括)到 toIndex(不包括)處所有元素集合組成的子集合 |
| Object[] toArray() | 將集合元素轉換為數組 |
| default void sort(Comparator<? super E> c) | 根據指定的比較器規則對集合元素排序(JDK 8新方法) |
3.2. ArrayList類
3.2.1.特點
- ArrayList是List接口的一個實現類,它是程序中最常見的一種集合
- ArrayList內部的數據存儲結構是數組形式
- 不適合做大量的增刪操作
- 遍歷和查找元素時顯得非常高效
3.2.2.語法
ArrayList list = new ArrayList(); list.add("stu1"); list.add("stu2"); System.out.println("集合的長度:" + list.size()); System.out.println("第2個元素是:" + list.get(1));3.3. LinkedList類
3.3.1.特點
- 內部包含有兩個Node類型的first和last屬性的雙向循環鏈表結構
- 遍歷和查找效率較低
- 增刪操作表現出很高的效率
3.3.2.底層原理
-
左圖為新增元素,圖中的元素1和元素2在集合中彼此為前后關系,在它們之間新增一個元素時,只需要讓元素1記住它后面的元素是新元素,讓元素2記住它前面的元素為新元素就可以了
-
右圖為刪除元素,要想刪除元素1和元素2之間的元素3,只需要讓元素1與元素2變成前后關系就可以了
3.3.3.特有方法
| void add(int index, E element) | 在此列表中指定的位置插入指定的元素。 |
| void addFirst(Object o) | 將指定元素插入集合的開頭 |
| void addLast(Object o) | 將指定元素添加到集合的結尾 |
| Object getFirst() | 返回集合的第一個元素 |
| Object getLast() | 返回集合的最后一個元素 |
| Object removeFirst() | 移除并返回集合的第一個元素 |
| Object removeLast() | 移除并返回集合的最后一個元素 |
| boolean offer(Object o) | 將指定元素添加到集合的結尾 |
| boolean offerFirst(Object o) | 將指定元素添加到集合的開頭 |
| boolean offerLast(Object o) | 將指定元素添加到集合的結尾 |
| Object peek() | 獲取集合的第一個元素 |
| Object peekFirst() | 獲取集合的第一個元素 |
| Object peekLast() | 獲取集合的最后一個元素 |
| Object poll() | 移除并返回集合的第一個元素 |
| Object pollFirst() | 移除并返回集合的第一個元素 |
| Object pollLast() | 移除并返回集合的最后一個元素 |
| void push(Object o) | 將指定元素添加到集合的開頭 |
| Object pop() | 移除并返回集合的第一個元素 |
3.3.4.語法
LinkedList link = new LinkedList(); link.add("stu1"); link.add("stu2"); link.offer("offer"); // 向集合尾部追加元素 link.push("push"); // 向集合頭部添加元素 Object object = link.peek(); //獲取集合第一個元素 link.removeFirst(); // 刪除集合第一個元素 link.pollLast(); // 刪除集合最后一個元素4.Collection集合遍歷
4.1. Iterator遍歷集合
4.1.1.工作原理
-
Iterator遍歷集合時,內部采用指針的方式來跟蹤集合中的元素。在調用next()方法之前,索引位于第一個元素之前,不指向任何元素
-
第一次調用next()方法后,索引會向后移動一位,指向第一個元素并將該元素返回
-
再次調用next()方法時,索引會指向第二個元素并將該元素返回
-
以此類推,直到hasNext()方法返回false,表示到達了集合的末尾終止對元素的遍歷
4.1.2.實現
int[] arr = new int[10]; ArrayList<Integer> list = new ArrayList<Integer>();for (int i = 0; i < arr.length; i++) {arr[i] = random.nextInt(100) + 1;list.add(arr[i]); } System.out.println(Arrays.toString(arr)); System.out.println(list);/*** 使用Iterator迭代器遍歷list集合*/ Iterator<Integer> iterator = list.iterator(); while (iterator.hasNext()) {Object obj = iterator.next();System.out.println(obj); }4.1.3.注意
- Iterator迭代器對集合中的元素進行迭代時,如果調用了集合對象的remove()方法刪除元素,會出現ConcurrentModificationException異常。
4.2. foreach遍歷集合
/*** 使用增強版for遍歷list集合*/ for (Object obj : list) {System.out.println(obj); }- 注意:foreach循環遍歷集合和數組時,只能訪問集合中的元素,不能對其中的元素進行修改
4.3. JDK8 ---- foreach遍歷集合
list.forEach(obj -> System.out.println(obj));4.4.forEachRemaining
- JDK 8中還針對Iterator迭代器對象提供了一個forEachRemaining(Consumer action)方法來進行遍歷,該方法同樣需要一個函數式接口
5.Set接口
5.1. Set接口簡介
5.1.1.特點
- Set接口和List接口一樣,同樣繼承自Collection接口
- Set接口中的元素無序,并且都會以某種規則保證存入的元素不出現重復
5.1.2.分類
| HashSet | 根據對象的哈希值來確定元素在集合中的存儲的位置,因此具有良好的存取和查找性能 |
| TreeSet | 以二叉樹的方式來存儲元素,它可以實現對集合中的元素進行排序 |
5.2. HashSet類
5.2.1.特點
- HashSet是Set接口的一個實現類,它所存儲的元素不可重復,并且無序
- 當向HashSet集合中添加一個元素時,首先會調用該元素的hashCode()方法來確定元素的存儲位置,然后再調用元素對象的equals()方法來確保該位置沒有重復元素
5.2.2.存儲原理
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-f9uP80fy-1634995158227)(https://i.loli.net/2021/10/22/Wl1HpNIjkamMBsO.png)]
- 在Java中,一些基本數據包裝類、String類等都已經默認重寫了hashCode()和equals()方法
- 開發者向HashSet集合中添加自定義的數據類型,如Student類時,必須增加重寫的hashCode()和equals()方法,才能保證數據的唯一性。
5.3. TreeSet類
5.3.1.特點
- TreeSet是Set接口的另一個實現類,它內部采用平衡二叉樹來存儲元素,來保證TreeSet集合中沒有重復的元素,并且可以對元素進行排序
- 二叉樹就是每個節點最多有兩個子節點的有序樹,每個節點及其子節點組成的樹稱為子樹,左側的節點稱為“左子樹”,右側的節點稱為“右子樹”,其中左子樹上的元素小于它的根結點,而右子樹上的元素大于它的根結點
5.3.2.存儲原理
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-kK8pDDQg-1634995158228)(https://i.loli.net/2021/10/22/VB7G4P2wLFvcZ3x.png)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-C5wSaJsG-1634995158229)(https://i.loli.net/2021/10/22/WHcuqkK2j9hvVUE.png)]
5.3.3.特有方法
| Object first() | 返回TreeSet集合的首個元素 |
| Object last() | 返回TreeSet集合的最后一個元素 |
| Object lower(Object o) | 返回TreeSet集合中小于給定元素的最大元素,如果沒有返回null |
| Object floor(Object o) | 返回TreeSet集合中小于或等于給定元素的最大元素,如果沒有返回null |
| Object higher(Object o) | 返回TreeSet集合中大于給定元素的最小元素,如果沒有返回null |
| Object ceiling(Object o) | 返回TreeSet集合中大于或等于給定元素的最小元素,如果沒有返回null |
| Object pollFirst() | 移除并返回集合的第一個元素 |
| Object pollLast() | 移除并返回集合的最后一個元素 |
5.3.4.排序
5.3.4.1.基本概念
- 向TreeSet集合添加元素時,都會調用compareTo()方法進行比較排序,該方法是Comparable接口中定義的,因此要想對集合中的元素進行排序,就必須實現Comparable接口
- Java中大部分的類都實現了Comparable接口,并默認實現了接口中的CompareTo()方法,如Integer、Double和String等
5.3.4.2.分類
- **自然排序:**要求存儲的元素類必須實現Comparable接口,并重寫compareTo()方法
- **定制排序:**要求自定義一個比較器,該比較器必須實現Comparator接口,并重寫compare()方法,然后將該比較器作為參數傳入集合的有參構造
5.3.4.2.主要區別
| 適合元素類本身未實現Comparable接口,無法進行比較 | 元素類本身實現Comparable接口 |
| 適合元素類實現的Comparable接口排序規則無法滿足用戶需求 | 依賴compareTo()方法的實現 |
| 會額外定義一個實現Comparator接口的比較器 | 實現Comparable接口排序規則比較單一,不利于后續改進 |
5.3.4.2.實現
- 自然排序
- 定制排序
6.Map接口
6.1. Map接口簡介
6.1.1.特點
- 雙列集合,它的每個元素都包含一個鍵對象Key和值對象Value,鍵和值對象之間存在一種對應關系,稱為映射
- Map中的映射關系是一對一的,一個鍵對象Key對應唯一一個值對象Value,其中鍵對象Key和值對象Value可以是任意數據類型,并且鍵對象Key不允許重復,這樣在訪問Map集合中的元素時,只要指定了Key,就能找到對應的Value
6.1.2.常用方法
| void put(Object key, Object value) | 向Map集合中添加指定鍵值映射的元素 |
| int size() | 返回Map集合鍵值對映射的個數 |
| Object get(Object key) | 返回指定鍵所映射的值,如果此映射不包含該鍵的映射關系,則返回null |
| boolean containsKey(Object key) | 查看Map集合中是否存在指定的鍵對象key |
| boolean containsValue(Object value) | 查看Map集合中是否存在指定的值對象value |
| Object remove(Object key) | 刪除并返回Map集合中指定鍵對象Key的鍵值映射元素 |
| void clear() | 清空整個Map集合中的鍵值映射元素 |
| Set keySet() | 以Set集合的形式返回Map集合中所有的鍵對象Key |
| Collection values() | 以Collection集合的形式返回Map集合中所有的值對象Value |
| Set<Map.Entry<Key,Value>> entrySet() | 將Map集合轉換為存儲元素類型為Map的Set集合 |
| Object getOrDefault(Object key, Object defaultValue) | 返回Map集合指定鍵所映射的值,如果不存在則返回默認值defaultValue(JDK 8新方法) |
| void forEach(BiConsumer action) | 通過傳入一個函數式接口對Map集合元素進行遍歷(JDK 8新方法) |
| Object putIfAbsent(Object key, Object value) | 向Map集合中添加指定鍵值映射的元素,如果集合中已存在該鍵值映射元素,則不再添加而是返回已存在的值對象Value(JDK 8新方法) |
| boolean remove(Object key, Object value) | 刪除Map集合中鍵值映射同時匹配的元素(JDK 8新方法) |
| boolean replace(Object key, Object value) | 將Map集合中指定鍵對象Key所映射的值修改為value(JDK 8新方法) |
6.2. HashMap類
6.2.1.特點
- HashMap集合是Map接口的一個實現類,它用于存儲鍵值映射關系,該集合的鍵和值允許為空,但鍵不能重復,且集合中的元素是無序的
- HashMap底層是由哈希表結構組成的,其實就是“數組+鏈表”的組合體,數組是HashMap的主體結構,鏈表則主要是為了解決哈希值沖突而存在的分支結構。正因為這樣特殊的存儲結構,HashMap集合對于元素的增、刪、改、查操作表現出的效率都比較高
6.2.2.內部結構
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-4krjYKEC-1634995158229)(https://i.loli.net/2021/10/22/DB63Y1yivjLanUt.png)]
- 在哈希表結構中,主體結構為圖中水平方向的數組結構,其長度稱為HashMap集合的容量(capacity)
- 數組結構垂直對應的是鏈表結構,鏈表結構稱為一個桶(bucket),每個桶的位置在集合中都有對應的桶值,用于快速定位集合元素添加、查找時的位置
6.2.3.存儲原理
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-RQQxqPEe-1634995158230)(https://i.loli.net/2021/10/22/msn9H6LrI2GWQRV.png)]
6.2.4.注意
-
使用HashMap集合時,如果通過鍵對象k定位到的桶位置不含鏈表結構,那么對于查找、添加等操作很快;如果定位到的桶位置包含鏈表結構,對于添加操作,其時間復雜度依然不大,因為最新的元素會插入鏈表頭部,只需要簡單改變引用鏈即可;而對于查找操作來講,此時就需要遍歷鏈表,然后通過鍵對象k的equals(k)方法逐一查找比對。
所以,從性能方面考慮,HashMap中的鏈表出現越少,性能才會越好,這就要求HashMap集合中的桶越多越好。
-
HashMap根據實際情況,內部實現了動態地分配桶數量的策略。
通過new HashMap()方法創建HashMap時,會默認集合容量capacity大小為16,加載因子loadFactor為0.75(HashMap桶多少權衡策略的經驗值),此時該集合桶的閥值就為12(容量capacity與加載因子loadFactor的乘積),如果向HashMap集合中不斷添加完全不同的鍵值對<k,v>,當超過12個存儲元素時,HashMap集合就會默認新增加一倍桶的數量(也就是集合的容量),此時集合容量就變為32。
6.2.4.LinkedHashMap
- HashMap集合并不保證集合元素存入和取出的順序
- 如果想讓這兩個順序一致,可以使用LinkedHashMap類,它是HashMap的子類。和LinkedList一樣也使用雙向鏈表來維護內部元素的關系,使LinkedHashMap元素迭代的順序與存入的順序一致
- 一般情況下,用的最多的是HashMap,在Map中插入、刪除和定位元素,HashMap 是最好的選擇。但如果需要輸出的順序和輸入的相同,那么用LinkedHashMap可以實現,它還可以按讀取順序來排列
6.3. Map集合遍歷
6.3.1.Iterator迭代器
- 遍歷思路:先將Map集合轉換為Iterator接口對象,然后進行遍歷。由于Map集合中元素是由鍵值對組成的,所以使用Iterator接口遍歷Map集合時,會有兩種將Map集合轉換為Iterator接口對象再進行遍歷的方法
- 遍歷方法:keySet()方法和entrySet()方法
6.3.1.1.keySet()方法
- 先將Map集合中所有鍵對象轉換為Set單列集合,接著將包含鍵對象的Set集合轉換為Iterator接口對象,然后遍歷Map集合中所有的鍵,再根據鍵獲取相應的值。
6.3.1.2.entrySet()方法
- 將原有Map集合中的鍵值對作為一個整體返回為Set集合,接著將包含鍵值對對象的Set集合轉換為Iterator接口對象,然后獲取集合中的所有的鍵值對映射關系,再從映射關系中取出鍵和值
6.3.2.JDK8提供的forEach
- JDK 8中,根據Lambda表達式特性新增了一個forEach(BiConsumer action)方法來遍歷Map集合,該方法所需要的參數也是一個函數式接口,因此可以使用Lambda表達式的書寫形式來進行集合遍歷
6.3.3.值遍歷—values()方法
- 在Map集合中,除了以上介紹的兩種主要的遍歷方式外,還提供了一個values()方法,通過這個方法可以直接獲取Map中存儲所有值的Collection集合
6.4. TreeMap集合
- 介紹: TreeMap集合是Map接口的另一個實現類,在TreeMap內部是通過二叉樹的原理來保證鍵的唯一性,這與TreeSet集合存儲的原理一樣,因此TreeMap中所有的鍵是按照某種順序排列的
- 說明:為了實現TreeMap元素排序,可以參考TreeSet 集合排序方式,使用自然排序和定制排序
comparator方式
import java.util.*; class CustomComparator implements Comparator {public int compara (Object obj1, Object obj2) {String key1 = (String) obj1;String key2 = (String) obj2;return key2.comparaTo(key1); //調用了String對象的comparaTo()方法} } public class Main {public static void main(String[] args) {Map map = new TreeMap(new CustomComparator());map.put("2", "Rose");map.put("1", Jack);map.put("3", "Luck");System.out.println(map);} } /*** 打印結果* {1=Jack, 2=Rose, 3=Luck}*/6.5. Properties集合
- 介紹: Map接口還有一個實現類Hashtable,它和HashMap十分相似,其中一個主要區別在于Hashtable是線程安全的
- 說明:Hashtable類有一個子類Properties,Properties主要用來存儲字符串類型的鍵和值,在實際開發中,經常使用**Properties集合類來存取應用的配置項**
7.泛型
7.1.why
- 集合中可以存儲任意類型的對象元素,但是當把一個對象存入集合后,集合會“忘記”這個對象的類型,將該對象從集合中取出時,這個對象的編譯類型就統一變成了Object類型
- 在程序中無法確定一個集合中的元素到底是什么類型,那么在取出元素時,如果進行強制類型轉換就很容易出錯
7.2.語法
ArrayList<參數化類型> list = new ArrayList<參數化類型>(); ArrayList<String> list = new ArrayList<String>();8.常用工具類
8.1. Collections工具類
8.1.1.添加、排序常用方法
| static boolean addAll(Collection<? super T> c, T… elements) | 將所有指定元素添加到指定集合c中 |
| static void reverse(List list) | 反轉指定List集合中元素的順序 |
| static void shuffle(List list) | 對List集合中的元素進行隨機排序 |
| static void sort(List list) | 根據元素的自然順序對List集合中的元素進行排序 |
| static void swap(List list,int i,int j) | 將指定List集合中角標i處元素和j處元素進行交換 |
8.1.2.查找、替換常用方法
| static int binarySearch(List list,Object key) | 使用二分法搜索指定對象在List集合中的索引,查找的List集合中的元素必須是有序的 |
| static Object max(Collection col) | 根據元素的自然順序,返回給定集合中最大的元素 |
| static Object min(Collection col) | 根據元素的自然順序,返回給定集合中最小的元素 |
| static boolean replaceAll(List list,Object oldVal,Object newVal) | 用一個新值newVal替換List集合中所有的舊值oldVal |
8.2. Arrays工具類
- sort() 排序
- binarySearch(Object[] obj, Object key) 用二分法查找obj中的key
- copyOfRange(int[] original, int from, int to) 復制數組的指定范圍
- fill(Object[] a, Object value) 用value把數組填充
- asList() 把Array轉換為List
- stream() 創建stream流對象
9.JDK8 ---- 聚合操作
9.1. 聚合操作簡介
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-vJ6Xj8KI-1634995158231)(https://i.loli.net/2021/10/23/GLnxOQerBAWDk3f.png)]
9.2. 創建Stream流對象
- 所有的Collections集合都可以使用stream()靜態方法獲取Stream流對象
- Stream接口的of()靜態方法可以獲取基本類型包裝類數組、引用類型數組和單個元素的Stream流對象
- Arrays工具類的stream()靜態方法也可以獲取數組元素的Stream流對象
- 注意:在進行聚合操作時,只是改變了Stream流對象中的數據,并不會改變原始集合或數組中的源數據
9.3. Stream流的常用方法
| Stream filter(Predicate<? super T> predicate) | 將指定流對象中的元素進行過濾,并返回一個子流對象 |
| Stream map(Function<? super T, ? extends R> mapper) | 將流中的元素按規則映射到另一個流中 |
| Stream distinct() | 刪除流中重復的元素 |
| Stream sorted() | 將流中的元素按自然順序排序 |
| Stream limit(long maxSize) | 截取流中元素的長度 |
| Stream skip(long n) | 丟棄流中前n個元素 |
| static Stream concat(Stream<? extends T> a, Stream<? extends T> b) | 將兩個流對象合并為一個流 |
| long count() | 統計流中元素的個數 |
| R collect(Collector<? super T, A, R> collector) | 將流中的元素收集到一個容器中(如集合) |
| Object[] toArray() | 將流中的元素收集到一個數組中 |
| void forEach(Consumer<? super T> action) | 將流中的元素進行遍歷 |
- forEach() 遍歷
- filter() 過濾
- map() 映射
- limit() 截取
- collect() 收集
9.4. Parallel Stream (并行流)
9.4.1.串并流對比
- 串行流(Serial Stream):將源數據轉換為一個流對象,然后在單線程下執行聚合操作的流(也就是單一管道流)
- 并行流(Parallel Stream):將源數據分為多個子流對象進行多線程操作(也就是多個管道流),然后將處理的結果再匯總為一個流對象
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-PJV0v5nD-1634995158231)(https://i.loli.net/2021/10/23/MR5B7quGU4O2bDJ.png)]
9.4.2.并行流創建
- 通過Collection集合接口的parallelStream()方法直接將集合類型的源數據轉變為Stream并行流
- 通過BaseStream接口的parallel()方法將Stream串行流轉變為Stream并行流
9.4.3.注意
-
創建Stream流對象時,除非有特別聲明,否則默認創建的都是串行流
-
使用Stream并行流在一定程度上可以提升程序的執行效率,但是在多線程執行就會出現線程安全這個大問題,所以為了能夠在聚合操作中使用Stream并行流,前提是要執行操作的源數據在并行執行過程中不會被修改
seStream接口的parallel()方法將Stream串行流轉變為Stream`并行流
import java.util.*; import java.util.stream.Stream; public class Main {public static void main(String[] args) {List<String> list = Arrays.asList("張三", "李四", "張小明", "張陽");// 1.直接使用Collection接口的parallelStream()創建并行流Stream<String> paralleStream = list.parallelStream();System.out.println(parallelStream.isParallel());// 創建一個Stream串行流Stream<String> stream = Stream.of("張三", "李四", "張小明", "張陽");// 2.使用BaseStream接口的parallel()方法將串行流變為并行流Stream<String> parallel = stream.parallel();System.out.println(parallel.isParallel());} } /*** 打印結果* true* true*/9.4.3.注意
-
創建Stream流對象時,除非有特別聲明,否則默認創建的都是串行流
-
使用Stream并行流在一定程度上可以提升程序的執行效率,但是在多線程執行就會出現線程安全這個大問題,所以為了能夠在聚合操作中使用Stream并行流,前提是要執行操作的源數據在并行執行過程中不會被修改
總結
- 上一篇: GD32 开机直接进入了深度睡眠模式导致
- 下一篇: 注意力机制 SE-Net 原理与 Ten