Java 8 Streams API:對Stream分組和分割槽
這篇文章展示瞭如何使用 Streams API 中的 Collector 及 groupingBy 和 partitioningBy 來對流中的元素進行分組和分割槽。
思考一下 Employee 物件流,每個物件對應一個名字、城市和銷售數量,如下表所示:
+----------+------------+-----------------+ | Name | City | Number of Sales | +----------+------------+-----------------+ | Alice | London | 200 | | Bob | London | 150 | | Charles | New York | 160 | | Dorothy | Hong Kong | 190 | +----------+------------+-----------------+
分組
首先,我們利用(lambda表示式出現之前的)命令式風格Java 程式對流中的僱員按城市進行分組:
Map<String, List<Employee>> result = new HashMap<>(); for (Employee e : employees) { String city = e.getCity(); List<Employee> empsInCity = result.get(city); if (empsInCity == null) { empsInCity = new ArrayList<>(); result.put(city, empsInCity); } empsInCity.add(e); }
你可能很熟悉寫這樣的程式碼,你也看到了,一個如此簡單的任務就需要這麼多程式碼!
而在 Java 8 中,你可以使用 groupingBy 收集器,一條語句就能完成相同的功能,像這樣:
Map<String, List<Employee>> employeesByCity = employees.stream().collect(groupingBy(Employee::getCity));
結果如下面的 map 所示:
{New York=[Charles], Hong Kong=[Dorothy], London=[Alice, Bob]}
還可以計算每個城市中僱員的數量,只需傳遞一個計數收集器給 groupingBy 收集器。第二個收集器的作用是在流分類的同一個組中對每個元素進行遞迴操作。
Map<String, Long> numEmployeesByCity = employees.stream().collect(groupingBy(Employee::getCity, counting()));
結果如下面的 map 所示:
{New York=1, Hong Kong=1, London=2}
順便提一下,該功能與下面的 SQL 語句是等同的:
select city, count(*) from Employee group by city
另一個例子是計算每個城市的平均年齡,這可以聯合使用 averagingInt 和 groupingBy 收集器:
Map<String, Double> avgSalesByCity = employees.stream().collect(groupingBy(Employee::getCity, averagingInt(Employee::getNumSales)));
結果如下 map 所示:
{New York=160.0, Hong Kong=190.0, London=175.0}
分割槽
分割槽是一種特殊的分組,結果 map 至少包含兩個不同的分組——一個true,一個false。例如,如果想找出最優秀的員工,你可以將所有僱員分為兩組,一組銷售量大於 N,另一組小於 N,使用 partitioningBy 收集器:
Map<Boolean, List<Employee>> partitioned = employees.stream().collect(partitioningBy(e -> e.getNumSales() > 150));
輸出如下結果:
{false=[Bob], true=[Alice, Charles, Dorothy]}
你也可以將 groupingBy 收集器傳遞給 partitioningBy 收集器來將聯合使用分割槽和分組。例如,你可以統計每個分割槽中的每個城市的僱員人數:
Map<Boolean, Map<String, Long>> result = employees.stream().collect(partitioningBy(e -> e.getNumSales() > 150, groupingBy(Employee::getCity, counting())));
這樣會生成一個二級 Map:
{false={London=1}, true={New York=1, Hong Kong=1, London=1}}
相關文章
- java .stream(). 使用介紹 Streams APIJavaAPI
- 8個實用的Java Streams APIJavaAPI
- Java8中的 lambda 和Stream APIJavaAPI
- Java8中的Stream APIJavaAPI
- Java8 Stream常用API整理JavaAPI
- Java8的Stream API使用JavaAPI
- java8 Stream APi 入門JavaAPI
- Java8新特性--Stream APIJavaAPI
- Java 8 Stream API 轉換到 Kotlin 集合APIJavaAPIKotlin
- MySql分表、分庫、分片和分割槽MySql
- Java8 - Stream API快速入門JavaAPI
- Java 8 Stream Api 中的 peek 操作JavaAPI
- Apache Spark:分割槽和分桶 - NiveditaApacheSpark
- hive分割槽和分桶你熟悉嗎?Hive
- hive分割槽分桶Hive
- oracle分割槽表和分割槽表exchangeOracle
- win10硬碟分割槽怎麼分_win10系統如何對硬碟分割槽Win10硬碟
- Java 8 Stream API: 深入理解與高效使用JavaAPI
- DM7,DM8和ORACLE中對分割槽split的區別Oracle
- Java 8 StreamJava
- oracle分割槽表和非分割槽表exchangeOracle
- Oracle分割槽表基礎運維-05組合分割槽Oracle運維
- hive 分割槽表和分桶表區別Hive
- Oracle分割槽表基礎運維-01分割槽表分類Oracle運維
- 對sd卡分割槽fat和ext4SD卡
- Oracle分割槽表基礎運維-06分割槽表索引Oracle運維索引
- win10分割槽使用mbr好還是gpt好_win10系統gpt分割槽和mbr分割槽的區別Win10GPT
- SSD固態硬碟要分割槽嗎?SSD固態硬碟分割槽與不分割槽的效能對比硬碟
- oracle 分割槽表move和包含分割槽表的lob moveOracle
- 移動分割槽表和分割槽索引的表空間索引
- Hive中靜態分割槽和動態分割槽總結Hive
- 13. 尚矽谷_Java8新特性_Stream API 練習JavaAPI
- Java 8 中Stream用法Java
- Java8——Stream流Java
- java 8 特性——stream流Java
- Java 8 新特性 StreamJava
- Java Stream API groupingBy()介紹JavaAPI
- Kafka訊息分發、主題分割槽與消費組的概念Kafka
- Hive的分割槽和排序Hive排序