Java 8 Streams API:对流进行分组和分区
這篇文章展示了如何使用Streams API中可用的Collectors將具有g(shù)roupingBy的流元素和具有partitioningBy的流元素進(jìn)行g(shù)roupingBy 。
考慮一系列Employee對(duì)象,每個(gè)對(duì)象都有名稱,城市和銷售數(shù)量,如下表所示:
+----------+------------+-----------------+ | Name | City | Number of Sales | +----------+------------+-----------------+ | Alice | London | 200 | | Bob | London | 150 | | Charles | New York | 160 | | Dorothy | Hong Kong | 190 | +----------+------------+-----------------+分組
讓我們開始使用命令式(Java-Lamba)按城市對(duì)員工進(jìn)行分組:
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); }您可能熟悉這樣的代碼編寫,并且您可以看到,完成如此簡(jiǎn)單的任務(wù)需要很多代碼!
在Java 8中,您可以使用groupingBy收集器對(duì)單個(gè)語(yǔ)句執(zhí)行相同的操作,如下所示:
Map<String, List<Employee>> employeesByCity =employees.stream().collect(groupingBy(Employee::getCity));結(jié)果如下圖:
{New York=[Charles], Hong Kong=[Dorothy], London=[Alice, Bob]}通過將counting收集器傳遞給groupingBy收集器,還可以計(jì)算每個(gè)城市的雇員counting 。 第二收集器對(duì)分類到同一組的流中的所有元素執(zhí)行進(jìn)一步的還原操作。
Map<String, Long> numEmployeesByCity =employees.stream().collect(groupingBy(Employee::getCity, counting()));結(jié)果如下圖:
{New York=1, Hong Kong=1, London=2}順便說一句,這等效于以下SQL語(yǔ)句:
select city, count(*) from Employee group by city另一個(gè)示例是計(jì)算每個(gè)城市的平均銷售數(shù)量,可以使用averagingInt收集器結(jié)合groupingBy收集器來完成:
Map<String, Double> avgSalesByCity =employees.stream().collect(groupingBy(Employee::getCity,averagingInt(Employee::getNumSales)));結(jié)果如下圖:
{New York=160.0, Hong Kong=190.0, London=175.0}分區(qū)
分區(qū)是一種特殊的分組,其中的結(jié)果映射最多包含兩個(gè)不同的組-一個(gè)用于true ,一個(gè)用于false 。 例如,如果您想找出最好的員工是誰(shuí),則可以使用partitioningBy收集器將他們劃分為銷售額大于N的員工和不屬于N的員工。
Map<Boolean, List<Employee>> partitioned =employees.stream().collect(partitioningBy(e -> e.getNumSales() > 150));這將產(chǎn)生以下結(jié)果:
{false=[Bob], true=[Alice, Charles, Dorothy]}您還可以通過將groupingBy收集器傳遞給partitioningBy收集器來組合分區(qū)和分組。 例如,您可以計(jì)算每個(gè)分區(qū)內(nèi)每個(gè)城市的雇員人數(shù):
Map<Boolean, Map<String, Long>> result =employees.stream().collect(partitioningBy(e -> e.getNumSales() > 150,groupingBy(Employee::getCity, counting())));這將產(chǎn)生一個(gè)兩層的Map:
{false={London=1}, true={New York=1, Hong Kong=1, London=1}}翻譯自: https://www.javacodegeeks.com/2015/11/java-8-streams-api-grouping-partitioning-stream.html
總結(jié)
以上是生活随笔為你收集整理的Java 8 Streams API:对流进行分组和分区的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑操作系统到底怎么装全新电脑如何装系统
- 下一篇: 曝台积电硅光子技术2025年有望放量产出