Java8 stream中的groupingBy
一、单字段、多字段分组
List<String> items = Arrays.asList("apple", "apple", "banana", "apple", "orange", "banana", "papaya"); Map<String, Long> result = items.stream().collect( Collectors.groupingBy( Function.identity(), Collectors.counting() ) ); System.out.println(result);
输出如下:
{papaya=1, orange=1, banana=2, apple=3}
在实际需求中,我们可能需要对一组对象进行分组,而且分组的条件有多个。比如对国家和产品类型进行双重分组,一种比较复杂的方法是先对产品类型进行分组,然后对每一个产品类型中的国家名进行分组求和。示例如下:
Map<String, List<item>> countMap = recordItems.stream().collect(Collectors.groupingBy(o -> o.getProductType())); List<Record> records = new ArrayList<Record>; countMap.keySet().forEach(productType -> { Map<String, Long> countMap1 = countMap.get(productType).stream().collect(Collectors.groupingBy(o -> o.getCountry(), Collectors.counting())); countMap1(key).stream().forEach(country -> { Record record = new Record(); record.set("device_type", productType); record.set("location", country; record.set("count", countMap1(key).intValue()); records.add(record); }); });
上面的方法在应对两个字段的分组要求时,还能应付的过来,但如果字段超过两个时,每增加一个字段,就会多出很多代码行,显然不太合理。更合理的方法是,增加一个 getKey()方法,返回多个字段组成的唯一key,比如通过下划线连接等等。示例如下:
// 分组统计 Map<String, Long> countMap = records.stream().collect(Collectors.groupingBy(o -> o.getProductType() + "_" + o.getCountry(), Collectors.counting())); List<Record> countRecords = countMap.keySet().stream().map(key -> { String[] temp = key.split("_"); String productType = temp[0]; String country = temp[1]; Record record = new Record(); record.set("device_type", productType); record.set("location", country; record.set("count", countMap.get(key).intValue()); return record; }).collect(Collectors.toList());
二、分组获取最新一条数据再合并成list
这种需求还是挺常见的List<MemberSolutionVo> list = new ArrayList<>(); ... Map<String, MemberSolutionVo> collect = list.stream().collect( Collectors.groupingBy(MemberSolutionVo::getUuid, Collectors.collectingAndThen(Collectors.reducing((c1, c2) -> c1.getSolutionId().intValue() > c2.getSolutionId().intValue() ? c1 : c2), Optional::get))); list = new ArrayList<>(collect.values());
参考文章:
https://www.jianshu.com/p/dd5121c8fa89
https://codeleading.com/article/40836192324

浙公网安备 33010602011771号