stream and lambda(18) - 終止操作之 stream 收集器 collectors
先定義初始值
private Stream<String> getStrStream() { return Stream.of("this", "is", "the", "the", "test", null); }
各種方法使用如下:
public void collectorTest() { //Collectors.toCollection 傳入一個承載結果的 Supplier ArrayList<String> toCollection = getStrStream().collect(Collectors.toCollection(ArrayList::new)); System.out.println("Collectors.toCollection 轉成 ArrayList 結果:" + toCollection); //Collectors.toList List<String> toList = getStrStream().collect(Collectors.toList()); System.out.println("Collectors.toList 結果:" + toList); //Collectors.toSet Set<String> toSet = getStrStream().collect(Collectors.toSet()); System.out.println("Collectors.toSet 去重後結果:" + toList); //Collectors.toMap 前兩個引數,分別是 key 和 value 的處理 //key 如果有重複會報錯,value 如果是 null 也會報錯 //Map<String, Integer> toMap = strings.stream().collect(Collectors.toMap( // Function.identity(), s -> s == null ? null : s.length())); //第三個引數是合併函式,我們可以用這個來去重 Map<String, Integer> toMap = getStrStream().collect(Collectors.toMap( Function.identity(), s -> s == null ? 0 : s.length(), (k1, k2) -> k2)); System.out.println("Collectors.toMap 預設 HashMap 亂序結果:" + toMap); //第四個引數是指定承載元素的Map,預設是使用HashMap,不過我們可以根據情況改 toMap = getStrStream().collect(Collectors.toMap( Function.identity(), s -> s == null ? 0 : s.length(), (k1, k2) -> k2, LinkedHashMap::new)); System.out.println("Collectors.toMap LinkedHashMap 有序結果:" + toMap); //toConcurrentMap 和 toMap 用法基本相同 //注意 ConcurrentHashMap 本身 key 和 value 都不可以為null ConcurrentMap<String, Integer> toConcurrentMap = getStrStream().collect(Collectors.toConcurrentMap( //使用 Function.identity() 會報NPE String::valueOf, s -> s == null ? 0 : s.length(), (k1, k2) -> k2)); System.out.println("Collectors.toConcurrentMap 結果:" + toConcurrentMap); // 等效於 Stream.count Long count = getStrStream().collect(Collectors.counting()); System.out.println("Collectors.counting 計數結果:" + count); // joining 可帶分隔符和左右的開始終止符 String join = getStrStream().collect(Collectors.joining()); System.out.println("Collectors.joining 無分隔符結果:" + join); join = getStrStream().collect(Collectors.joining(",")); System.out.println("Collectors.joining 有分隔符結果:" + join); join = getStrStream().collect(Collectors.joining(",", "[", "]")); System.out.println("Collectors.joining 有分隔符和左右護法結果:" + join); // 等效於 Stream.min Optional<String> min = getStrStream().map(String::valueOf) .collect(Collectors.minBy(Comparator.naturalOrder())); System.out.println("Collectors.minBy 結果:" + min.orElse("")); // 等效於 Stream.max Optional<String> max = getStrStream().map(String::valueOf) .collect(Collectors.minBy(Comparator.reverseOrder())); System.out.println("Collectors.maxBy 結果:" + max.orElse("")); //等效於 Stream.reduce String reduce = getStrStream().collect(Collectors.reducing("", (s1, s2) -> s1 + "\t" + s2)); System.out.println("Collectors.reducing 結果:" + reduce); Double average = getStrStream().collect( Collectors.averagingInt(value -> String.valueOf(value).length())); System.out.println("Collectors.averagingInt 平均值結果:" + average); IntSummaryStatistics summarizingInt = getStrStream().collect(Collectors.summarizingInt(value -> String.valueOf(value).length())); System.out.println("Collectors.summarizingInt 結果:" + summarizingInt); Integer collectingAndThen = getStrStream().collect(Collectors.collectingAndThen(Collectors.toList(), List::size)); System.out.println("Collectors.collectingAndThen 先轉List再取size 結果:" + collectingAndThen); //等效於 Stream.map().collect() List<String> mapping = getStrStream().collect( Collectors.mapping(String::valueOf, Collectors.toList())); System.out.println("Collectors.mapping 結果:" + mapping); Map<Integer, List<String>> groupingBy = getStrStream().collect( Collectors.groupingBy(s -> String.valueOf(s).length())); System.out.println("Collectors.groupingBy 按字母個數分組結果:" + groupingBy); Map<Integer, Long> groupingBy2 = getStrStream().collect( Collectors.groupingBy(s -> String.valueOf(s).length(), Collectors.counting())); System.out.println("Collectors.groupingBy 按字母個數分組,分組統計個數,結果:" + groupingBy2); LinkedHashMap<Integer, Long> groupingBy3 = getStrStream().collect( Collectors.groupingBy(s -> String.valueOf(s).length(), LinkedHashMap::new, Collectors.counting())); System.out.println("Collectors.groupingBy 按字母個數分組,分組統計個數,存放在LinkedHashMap結果:" + groupingBy3); //groupingByConcurrent 和 groupingBy 用法是基本是一樣的 Map<Integer, List<String>> groupingByConcurrent = getStrStream().collect( Collectors.groupingByConcurrent(s -> String.valueOf(s).length())); System.out.println("Collectors.groupingByConcurrent 按字母個數分組結果:" + groupingByConcurrent); //partitioningBy 和 groupingBy 的主要區別是,只能按布林型別來分組 Map<Boolean, List<String>> partitioningBy = getStrStream().collect( Collectors.partitioningBy(s -> String.valueOf(s).length() > 3)); System.out.println("Collectors.partitioningBy 按字母長度分塊,結果:" + partitioningBy); Map<Boolean, Long> partitioningBy2 = getStrStream().collect(Collectors.partitioningBy(s -> String.valueOf(s).length() > 3, Collectors.counting())); System.out.println("Collectors.partitioningBy 按字母個數分塊並統計結果:" + partitioningBy2); }
輸出如下:
Collectors.toCollection 轉成 ArrayList 結果:[this, is, the, the, test, null]
Collectors.toList 結果:[this, is, the, the, test, null]
Collectors.toSet 去重後結果:[this, is, the, the, test, null]
Collectors.toMap 預設 HashMap 亂序結果:{null=0, the=3, test=4, this=4, is=2}
Collectors.toMap LinkedHashMap 有序結果:{this=4, is=2, the=3, test=4, null=0}
Collectors.toConcurrentMap 結果:{the=3, test=4, null=0, this=4, is=2}
Collectors.counting 計數結果:6
Collectors.joining 無分隔符結果:thisisthethetestnull
Collectors.joining 有分隔符結果:this,is,the,the,test,null
Collectors.joining 有分隔符和左右護法結果:[this,is,the,the,test,null]
Collectors.minBy 結果:is
Collectors.maxBy 結果:this
Collectors.reducing 結果: this is the the test null
Collectors.averagingInt 平均值結果:3.3333333333333335
Collectors.summarizingInt 結果:IntSummaryStatistics{count=6, sum=20, min=2, average=3.333333, max=4}
Collectors.collectingAndThen 先轉List再取size 結果:6
Collectors.mapping 結果:[this, is, the, the, test, null]
Collectors.groupingBy 按字母個數分組結果:{2=[is], 3=[the, the], 4=[this, test, null]}
Collectors.groupingBy 按字母個數分組,分組統計個數,結果:{2=1, 3=2, 4=3}
Collectors.groupingBy 按字母個數分組,分組統計個數,存放在LinkedHashMap結果:{4=3, 2=1, 3=2}
Collectors.groupingByConcurrent 按字母個數分組結果:{2=[is], 3=[the, the], 4=[this, test, null]}
Collectors.partitioningBy 按字母長度分塊,結果:{false=[is, the, the], true=[this, test, null]}
Collectors.partitioningBy 按字母個數分塊並統計結果:{false=3, true=3}
總結
- Collectors 提供的部分收集器,其實使用部分終止操作方法更簡單。
- Collectors 提供的收集器,基礎上可以滿足我們日常的編碼需求,如果有特殊情況,可以直接使用 collect 方法傳普通引數。
- 部分收集器,組合起來使用,效果更好。
- 收集器的使用,還是要多練習才能更好的掌握。
- stream and lambda(18) - 終止操作之 stream 收集器 collectors
- stream and lambda(15) - 終止操作之 stream 陣列操作 toArray
- stream and lambda(13) - 終止操作之計數 count 與比較 min、max
- stream and lambda(12) - 終止操作之查詢與匹配(findAny、findFirst、allMatch、anyMatch、noneMatch)
- stream and lambda(11) - Optional 簡介
- stream and lambda(10) - 中間操作之排序sorted與除錯peek
- stream and lambda(9) - 中間操作之map操作(map、flatmap)
- stream and lambda(8) - 中間操作之篩選操作(filter、distinct、limit、skip)
- stream and lambda(7) - stream 的建立
- stream and lambda(6) - stream 簡介
- stream and lambda(5) - lambda 表示式最佳實踐
- stream and lambda(3) - jdk 提供的函式式介面
- stream and lambda(2) - 函式式介面簡介
- stream and lambda(1) - lambda 簡介