collectors.groupingby根据一个或多个属性对集合中的项目进行分组

数据准备:

public product(long id, integer num, bigdecimal price, string name, string category) {
 this.id = id;
 this.num = num;
 this.price = price;
 this.name = name;
 this.category = category;
}
 
product prod1 = new product(1l, 1, new bigdecimal("15.5"), "面包", "零食");
product prod2 = new product(2l, 2, new bigdecimal("20"), "饼干", "零食");
product prod3 = new product(3l, 3, new bigdecimal("30"), "月饼", "零食");
product prod4 = new product(4l, 3, new bigdecimal("10"), "青岛啤酒", "啤酒");
product prod5 = new product(5l, 10, new bigdecimal("15"), "百威啤酒", "啤酒");
list<product> prodlist = lists.newarraylist(prod1, prod2, prod3, prod4, prod5);

分组

按照类目分组:

map<string, list<product>> prodmap= prodlist.stream().collect(collectors.groupingby(product::getcategory));
 
//{"啤酒":[{"category":"啤酒","id":4,"name":"青岛啤酒","num":3,"price":10},{"category":"啤酒","id":5,"name":"百威啤酒","num":10,"price":15}],"零食":[{"category":"零食","id":1,"name":"面包","num":1,"price":15.5},{"category":"零食","id":2,"name":"饼干","num":2,"price":20},{"category":"零食","id":3,"name":"月饼","num":3,"price":30}]}

按照几个属性拼接分组:

map<string, list<product>> prodmap = prodlist.stream().collect(collectors.groupingby(item -> item.getcategory() + "_" + item.getname()));
 
//{"零食_月饼":[{"category":"零食","id":3,"name":"月饼","num":3,"price":30}],"零食_面包":[{"category":"零食","id":1,"name":"面包","num":1,"price":15.5}],"啤酒_百威啤酒":[{"category":"啤酒","id":5,"name":"百威啤酒","num":10,"price":15}],"啤酒_青岛啤酒":[{"category":"啤酒","id":4,"name":"青岛啤酒","num":3,"price":10}],"零食_饼干":[{"category":"零食","id":2,"name":"饼干","num":2,"price":20}]}

根据不同条件分组

map<string, list<product>> prodmap= prodlist.stream().collect(collectors.groupingby(item -> {
 if(item.getnum() < 3) {
 return "3";
 }else {
 return "other";
 }
}));
 
//{"other":[{"category":"零食","id":3,"name":"月饼","num":3,"price":30},{"category":"啤酒","id":4,"name":"青岛啤酒","num":3,"price":10},{"category":"啤酒","id":5,"name":"百威啤酒","num":10,"price":15}],"3":[{"category":"零食","id":1,"name":"面包","num":1,"price":15.5},{"category":"零食","id":2,"name":"饼干","num":2,"price":20}]}

多级分组

要实现多级分组,我们可以使用一个由双参数版本的collectors.groupingby工厂方法创 建的收集器,它除了普通的分类函数之外,还可以接受collector类型的第二个参数。那么要进 行二级分组的话,我们可以把一个内层groupingby传递给外层groupingby,并定义一个为流 中项目分类的二级标准。

map<string, map<string, list<product>>> prodmap= prodlist.stream().collect(collectors.groupingby(product::getcategory, collectors.groupingby(item -> {
 if(item.getnum() < 3) {
 return "3";
 }else {
 return "other";
 }
})));
 
//{"啤酒":{"other":[{"category":"啤酒","id":4,"name":"青岛啤酒","num":3,"price":10},{"category":"啤酒","id":5,"name":"百威啤酒","num":10,"price":15}]},"零食":{"other":[{"category":"零食","id":3,"name":"月饼","num":3,"price":30}],"3":[{"category":"零食","id":1,"name":"面包","num":1,"price":15.5},{"category":"零食","id":2,"name":"饼干","num":2,"price":20}]}}

按子组收集数据

求总数

map<string, long> prodmap = prodlist.stream().collect(collectors.groupingby(product::getcategory, collectors.counting()));
 
//{"啤酒":2,"零食":3}

求和

map<string, integer> prodmap = prodlist.stream().collect(collectors.groupingby(product::getcategory, collectors.summingint(product::getnum)));
 
//{"啤酒":13,"零食":6}

把收集器的结果转换为另一种类型

map<string, product> prodmap = prodlist.stream().collect(collectors.groupingby(product::getcategory, collectors.collectingandthen(collectors.maxby(comparator.comparingint(product::getnum)), optional::get)));
 
//{"啤酒":{"category":"啤酒","id":5,"name":"百威啤酒","num":10,"price":15},"零食":{"category":"零食","id":3,"name":"月饼","num":3,"price":30}}

联合其他收集器

map<string, set<string>> prodmap = prodlist.stream().collect(collectors.groupingby(product::getcategory, collectors.mapping(product::getname, collectors.toset())));
 
//{"啤酒":["青岛啤酒","百威啤酒"],"零食":["面包","饼干","月饼"]}

到此这篇关于java8中的collectors.groupingby用法详解的文章就介绍到这了,更多相关java8 collectors.groupingby 内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!