前述
Collectors.groupingBy:根据一个或多个属性对集合中的项目进行分组
peek函数:改变对象里的值
实体类
public class Product {
private Long id;
private Integer num;
private BigDecimal price;
private String name;
private String category;
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;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
@Override
public String toString() {
return "Product{" +
"id=" + id +
", num=" + num +
", price=" + price +
", name='" + name + '\'' +
", category='" + category + '\'' +
'}';
}
}
测试代码–Collectors.groupingBy
public class test {
public static void main(String[] args) {
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);
System.out.println("===================按照类目分组=================================");
Map<String, List<Product>> prodMap1 = prodList.stream().collect(Collectors.groupingBy(Product::getCategory));
for (String key : prodMap1.keySet()) {
System.out.println(key + ": " + prodMap1.get(key).toString());
}
// 运行结果
// 啤酒: [Product{id=4, num=3, price=10, name='青岛啤酒', category='啤酒'}, Product{id=5, num=10, price=15, name='百威啤酒', category='啤酒'}]
// 零食: [Product{id=1, num=1, price=15.5, name='面包', category='零食'}, Product{id=2, num=2, price=20, name='饼干', category='零食'}, Product{id=3, num=3, price=30, name='月饼', category='零食'}]
System.out.println("===================按照几个属性拼接分组===========================");
Map<String, List<Product>> prodMap2 = prodList.stream().collect(Collectors.groupingBy(item -> item.getCategory() + "_" + item.getName()));
for (String key : prodMap2.keySet()) {
System.out.println(key + ": " + prodMap2.get(key).toString());
}
// 运行结果
// 零食_月饼: [Product{id=3, num=3, price=30, name='月饼', category='零食'}]
// 零食_面包: [Product{id=1, num=1, price=15.5, name='面包', category='零食'}]
// 啤酒_百威啤酒: [Product{id=5, num=10, price=15, name='百威啤酒', category='啤酒'}]
// 啤酒_青岛啤酒: [Product{id=4, num=3, price=10, name='青岛啤酒', category='啤酒'}]
// 零食_饼干: [Product{id=2, num=2, price=20, name='饼干', category='零食'}]
System.out.println("=====================根据不同条件分组==============================");
Map<String, List<Product>> prodMap3 = prodList.stream().collect(Collectors.groupingBy(item -> {
if (item.getNum() < 3) {
return "more";
} else {
return "other";
}
}));
for (String key : prodMap3.keySet()) {
System.out.println(key + ": " + prodMap3.get(key).toString());
}
// 运行结果
// other: [Product{id=3, num=3, price=30, name='月饼', category='零食'}, Product{id=4, num=3, price=10, name='青岛啤酒', category='啤酒'}, Product{id=5, num=10, price=15, name='百威啤酒', category='啤酒'}]
// more: [Product{id=1, num=1, price=15.5, name='面包', category='零食'}, Product{id=2, num=2, price=20, name='饼干', category='零食'}]
System.out.println("=================多级分组(二级分组)============================");
// 要实现多级分组,我们可以使用一个由双参数版本的Collectors.groupingBy工厂方法创建的收集器,它除了普通的分类函数之外,还可以接受collector类型的第二个参数。
// 那么要进 行二级分组的话,我们可以把一个内层groupingBy传递给外层groupingBy,并定义一个为流中项目分类的二级标准。
Map<String, Map<String, List<Product>>> prodMap4 = prodList.stream().collect(Collectors.groupingBy(Product::getCategory, Collectors.groupingBy(item -> {
if (item.getNum() < 3) {
return "more";
} else {
return "other";
}
})));
for (String key : prodMap4.keySet()) {
System.out.println(key + ": " + prodMap4.get(key).toString());
}
// 运行结果
// 啤酒: {other=[Product{id=4, num=3, price=10, name='青岛啤酒', category='啤酒'}, Product{id=5, num=10, price=15, name='百威啤酒', category='啤酒'}]}
// 零食: {other=[Product{id=3, num=3, price=30, name='月饼', category='零食'}], 3=[Product{id=1, num=1, price=15.5, name='面包', category='零食'}, Product{id=2, num=2, price=20, name='饼干', category='零食'}]}
System.out.println("=====================按子组收集数据 求总数======================");
Map<String, Long> prodMap5 = prodList.stream().collect(Collectors.groupingBy(Product::getCategory, Collectors.counting()));
for (String key : prodMap5.keySet()) {
System.out.println(key + ": " + prodMap5.get(key).toString());
}
// 运行结果
// 啤酒: 2
// 零食: 3
System.out.println("===============================按子组收集数据 求和====================");
Map<String, Integer> prodMap6 = prodList.stream().collect(Collectors.groupingBy(Product::getCategory, Collectors.summingInt(Product::getNum)));
for (String key : prodMap6.keySet()) {
System.out.println(key + ": " + prodMap6.get(key).toString());
}
// 运行结果
// 啤酒: 13
// 零食: 6
System.out.println("====================把收集器的结果转换为另一种类型==============================");
Map<String, Product> prodMap7 = prodList.stream().collect(Collectors.groupingBy(Product::getCategory, Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparingInt(Product::getNum)), Optional::get)));
for (String key : prodMap7.keySet()) {
System.out.println(key + ": " + prodMap7.get(key).toString());
}
// 运行结果
// 啤酒: Product{id=5, num=10, price=15, name='百威啤酒', category='啤酒'}
// 零食: Product{id=3, num=3, price=30, name='月饼', category='零食'}
System.out.println("=====================联合其他收集器=====================================");
Map<String, Set<String>> prodMap8 = prodList.stream().collect(Collectors.groupingBy(Product::getCategory, Collectors.mapping(Product::getName, Collectors.toSet())));
for (String key : prodMap8.keySet()) {
System.out.println(key + ": " + prodMap8.get(key).toString());
}
// 运行结果
// 啤酒: [青岛啤酒, 百威啤酒]
// 零食: [面包, 饼干, 月饼]
}
}
测试代码–peek
public class test {
public static void main(String[] args) {
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);
System.out.println("===============================按子组收集数据 求和 不使用peek函数处理====================");
Map<String, Integer> prodMap9 = prodList.stream()
.peek(product -> product.setNum(product.getNum()))
.collect(Collectors.groupingBy(Product::getCategory, Collectors.summingInt(Product::getNum)))
.entrySet().stream().collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(v1, v2) -> v1,
HashMap::new
));
for (String key : prodMap9.keySet()) {
System.out.println(key + ": " + prodMap9.get(key).toString());
}
// 运行结果
// 啤酒: 13
// 零食: 6
System.out.println("===============================按子组收集数据 求和 使用peek函数处理====================");
Map<String, Integer> prodMap10 = prodList.stream()
.peek(product -> product.setNum(product.getNum() + 2))
.collect(Collectors.groupingBy(Product::getCategory, Collectors.summingInt(Product::getNum)))
.entrySet().stream().collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(v1, v2) -> v1,
HashMap::new
));
for (String key : prodMap10.keySet()) {
System.out.println(key + ": " + prodMap10.get(key).toString());
}
// 运行结果
// 啤酒: 17
// 零食: 12
}
}