- 簡介
- Collectors.toList()
- Collectors.toSet()
- Collectors.toCollection()
- Collectors.toMap()
- Collectors.collectingAndThen()
- Collectors.joining()
- Collectors.counting()
- Collectors.summarizingDouble/Long/Int()
- Collectors.averagingDouble/Long/Int()
- Collectors.summingDouble/Long/Int()
- Collectors.maxBy()/minBy()
- Collectors.groupingBy()
- Collectors.partitioningBy()
- 總結
java stream中Collectors的用法
簡介
在java stream中,我們通常需要將處理后的stream轉換成集合類,這個時候就需要用到stream.collect方法。collect方法需要傳入一個Collector類型,要實現Collector還是很麻煩的,需要實現好幾個接口。
於是java提供了更簡單的Collectors工具類來方便我們構建Collector。
下面我們將會具體講解Collectors的用法。
假如我們有這樣兩個list:
List<String> list = Arrays.asList("jack", "bob", "alice", "mark");
List<String> duplicateList = Arrays.asList("jack", "jack", "alice", "mark");
上面一個是無重復的list,一個是帶重復數據的list。接下來的例子我們會用上面的兩個list來講解Collectors的用法。
Collectors.toList()
List<String> listResult = list.stream().collect(Collectors.toList());
log.info("{}",listResult);
將stream轉換為list。這里轉換的list是ArrayList,如果想要轉換成特定的list,需要使用toCollection方法。
Collectors.toSet()
Set<String> setResult = list.stream().collect(Collectors.toSet());
log.info("{}",setResult);
toSet將Stream轉換成為set。這里轉換的是HashSet。如果需要特別指定set,那么需要使用toCollection方法。
因為set中是沒有重復的元素,如果我們使用duplicateList來轉換的話,會發現最終結果中只有一個jack。
Set<String> duplicateSetResult = duplicateList.stream().collect(Collectors.toSet());
log.info("{}",duplicateSetResult);
Collectors.toCollection()
上面的toMap,toSet轉換出來的都是特定的類型,如果我們需要自定義,則可以使用toCollection()
List<String> custListResult = list.stream().collect(Collectors.toCollection(LinkedList::new));
log.info("{}",custListResult);
上面的例子,我們轉換成了LinkedList。
Collectors.toMap()
toMap接收兩個參數,第一個參數是keyMapper,第二個參數是valueMapper:
Map<String, Integer> mapResult = list.stream()
.collect(Collectors.toMap(Function.identity(), String::length));
log.info("{}",mapResult);
如果stream中有重復的值,則轉換會報IllegalStateException異常:
Map<String, Integer> duplicateMapResult = duplicateList.stream()
.collect(Collectors.toMap(Function.identity(), String::length));
怎么解決這個問題呢?我們可以這樣:
Map<String, Integer> duplicateMapResult2 = duplicateList.stream()
.collect(Collectors.toMap(Function.identity(), String::length, (item, identicalItem) -> item));
log.info("{}",duplicateMapResult2);
在toMap中添加第三個參數mergeFunction,來解決沖突的問題。
Collectors.collectingAndThen()
collectingAndThen允許我們對生成的集合再做一次操作。
List<String> collectAndThenResult = list.stream()
.collect(Collectors.collectingAndThen(Collectors.toList(), l -> {return new ArrayList<>(l);}));
log.info("{}",collectAndThenResult);
Collectors.joining()
Joining用來連接stream中的元素:
String joinResult = list.stream().collect(Collectors.joining());
log.info("{}",joinResult);
String joinResult1 = list.stream().collect(Collectors.joining(" "));
log.info("{}",joinResult1);
String joinResult2 = list.stream().collect(Collectors.joining(" ", "prefix","suffix"));
log.info("{}",joinResult2);
可以不帶參數,也可以帶一個參數,也可以帶三個參數,根據我們的需要進行選擇。
Collectors.counting()
counting主要用來統計stream中元素的個數:
Long countResult = list.stream().collect(Collectors.counting());
log.info("{}",countResult);
Collectors.summarizingDouble/Long/Int()
SummarizingDouble/Long/Int為stream中的元素生成了統計信息,返回的結果是一個統計類:
IntSummaryStatistics intResult = list.stream()
.collect(Collectors.summarizingInt(String::length));
log.info("{}",intResult);
輸出結果:
22:22:35.238 [main] INFO com.flydean.CollectorUsage - IntSummaryStatistics{count=4, sum=16, min=3, average=4.000000, max=5}
Collectors.averagingDouble/Long/Int()
averagingDouble/Long/Int()對stream中的元素做平均:
Double averageResult = list.stream().collect(Collectors.averagingInt(String::length));
log.info("{}",averageResult);
Collectors.summingDouble/Long/Int()
summingDouble/Long/Int()對stream中的元素做sum操作:
Double summingResult = list.stream().collect(Collectors.summingDouble(String::length));
log.info("{}",summingResult);
Collectors.maxBy()/minBy()
maxBy()/minBy()根據提供的Comparator,返回stream中的最大或者最小值:
Optional<String> maxByResult = list.stream().collect(Collectors.maxBy(Comparator.naturalOrder()));
log.info("{}",maxByResult);
Collectors.groupingBy()
GroupingBy根據某些屬性進行分組,並返回一個Map:
Map<Integer, Set<String>> groupByResult = list.stream()
.collect(Collectors.groupingBy(String::length, Collectors.toSet()));
log.info("{}",groupByResult);
Collectors.partitioningBy()
PartitioningBy是一個特別的groupingBy,PartitioningBy返回一個Map,這個Map是以boolean值為key,從而將stream分成兩部分,一部分是匹配PartitioningBy條件的,一部分是不滿足條件的:
Map<Boolean, List<String>> partitionResult = list.stream()
.collect(Collectors.partitioningBy(s -> s.length() > 3));
log.info("{}",partitionResult);
看下運行結果:
22:39:37.082 [main] INFO com.flydean.CollectorUsage - {false=[bob], true=[jack, alice, mark]}
結果被分成了兩部分。
總結
Collectors是一個非常強大的工具類,希望大家能夠靈活使用。
本文的例子https://github.com/ddean2009/learn-java-streams/tree/master/Collectors
歡迎關注我的公眾號:程序那些事,更多精彩等着您!
更多內容請訪問 www.flydean.com