java8 streams
这篇文章展示了如何使用Streams API中可用的Collectors将具有groupingBy的流元素和具有partitioningBy的流元素进行groupingBy 。
考虑一系列Employee对象,每个对象都有名称,城市和销售数量,如下表所示:
+----------+------------+-----------------+
| Name | City | Number of Sales |
+----------+------------+-----------------+
| Alice | London | 200 |
| Bob | London | 150 |
| Charles | New York | 160 |
| Dorothy | Hong Kong | 190 |
+----------+------------+-----------------+分组
让我们开始使用命令式(Java-Lamba)按城市对员工进行分组:
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));结果如下图:
{New York=[Charles], Hong Kong=[Dorothy], London=[Alice, Bob]} 通过将counting收集器传递给groupingBy收集器,还可以计算每个城市的雇员counting 。 第二收集器对分类为同一组的流中的所有元素执行进一步的还原操作。
Map<String, Long> numEmployeesByCity =employees.stream().collect(groupingBy(Employee::getCity, counting()));结果如下图:
{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)));结果如下图:
{New York=160.0, Hong Kong=190.0, London=175.0}分区
分区是一种特殊的分组,其中的结果映射最多包含两个不同的组-一个用于true ,一个用于false 。 例如,如果您想找出最好的员工是谁,则可以使用partitioningBy收集器将他们分为销售额超过N的员工和销售额不超过N的员工。
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}}翻译自: https://www.javacodegeeks.com/2015/11/java-8-streams-api-grouping-partitioning-stream.html
java8 streams