首页 > 编程语言 >Java8 Stream --groupingBy 分组讲解

Java8 Stream --groupingBy 分组讲解

时间:2023-05-18 09:12:14浏览次数:30  
标签:Stream stream Collectors map -- groupingBy 分组 public

本文主要讲解:Java 8 Stream之Collectors.groupingBy()分组示例

Collectors.groupingBy() 分组之常见用法

功能代码:

/**
     * 使用java8 stream groupingBy操作,按城市分组list
     */
    public void groupingByCity() {
        Map<String, List<Employee>> map = employees.stream().collect(Collectors.groupingBy(Employee::getCity));
​
        map.forEach((k, v) -> {
            System.out.println(k + " = " + v);
        });
    }

Collectors.groupingBy() 分组之统计每个分组的count

功能代码:

/**
     * 使用java8 stream groupingBy操作,按城市分组list统计count
     */
    public void groupingByCount() {
        Map<String, Long> map = employees.stream()
                .collect(Collectors.groupingBy(Employee::getCity, Collectors.counting()));
​
        map.forEach((k, v) -> {
            System.out.println(k + " = " + v);
        });
    }

Collectors.groupingBy() 分组之统计分组平均值

功能代码:

/**
     * 使用java8 stream groupingBy操作,按城市分组list并计算分组年龄平均值
     */
    public void groupingByAverage() {
        Map<String, Double> map = employees.stream()
                .collect(Collectors.groupingBy(Employee::getCity, Collectors.averagingInt(Employee::getAge)));
​
        map.forEach((k, v) -> {
            System.out.println(k + " = " + v);
        });
    }

Collectors.groupingBy() 分组之统计分组总值

功能代码:

/**
     * 使用java8 stream groupingBy操作,按城市分组list并计算分组销售总值
     */
    public void groupingBySum() {
        Map<String, Long> map = employees.stream()
                .collect(Collectors.groupingBy(Employee::getCity, Collectors.summingLong(Employee::getAmount)));
​
        map.forEach((k, v) -> {
            System.out.println(k + " = " + v);
        });
​
        // 对Map按照分组销售总值逆序排序
        Map<String, Long> sortedMap = new LinkedHashMap<>();
        map.entrySet().stream().sorted(Map.Entry.<String, Long> comparingByValue().reversed())
                .forEachOrdered(e -> sortedMap.put(e.getKey(), e.getValue()));
​
        sortedMap.forEach((k, v) -> {
            System.out.println(k + " = " + v);
        });
    }

Collectors.groupingBy() 分组之Join分组List

功能代码:

/**
     * 使用java8 stream groupingBy操作,按城市分组list并通过join操作连接分组list中的对象的name 属性使用逗号分隔
     */
    public void groupingByString() {
        Map<String, String> map = employees.stream().collect(Collectors.groupingBy(Employee::getCity,
                Collectors.mapping(Employee::getName, Collectors.joining(", ", "Names: [", "]"))));
​
        map.forEach((k, v) -> {
            System.out.println(k + " = " + v);
        });
    } 

Collectors.groupingBy() 分组之转换分组结果List -> List

功能代码:

/**
     * 使用java8 stream groupingBy操作,按城市分组list,将List转化为name的List
     */
    public void groupingByList() {
        Map<String, List<String>> map = employees.stream().collect(
                Collectors.groupingBy(Employee::getCity, Collectors.mapping(Employee::getName, Collectors.toList())));
​
        map.forEach((k, v) -> {
            System.out.println(k + " = " + v);
            v.stream().forEach(item -> {
                System.out.println("item = " + item);
            });
        });
    }

Collectors.groupingBy() 分组之转换分组结果List -> Set

功能代码:

/**
     * 使用java8 stream groupingBy操作,按城市分组list,将List转化为name的Set
     */
    public void groupingBySet() {
        Map<String, Set<String>> map = employees.stream().collect(
                Collectors.groupingBy(Employee::getCity, Collectors.mapping(Employee::getName, Collectors.toSet())));
​
        map.forEach((k, v) -> {
            System.out.println(k + " = " + v);
            v.stream().forEach(item -> {
                System.out.println("item = " + item);
            });
        });
    }

Collectors.groupingBy() 分组之使用对象分组List

功能代码:

/**
	 * 使用java8 stream groupingBy操作,通过Object对象的成员分组List
	 */
	public void groupingByObject() {
		Map<Manage, List<Employee>> map = employees.stream().collect(Collectors.groupingBy(item -> {
			return new Manage(item.getName());
		}));

		map.forEach((k, v) -> {
			System.out.println(k + " = " + v);
		});
	}

Collectors.groupingBy() 分组之使用两个成员分组List

功能代码:

/**
	 * 使用java8 stream groupingBy操作, 基于city 和name 实现多次分组
	 */
	public void groupingBys() {
		Map<String, Map<String, List<Employee>>> map = employees.stream()
				.collect(Collectors.groupingBy(Employee::getCity, Collectors.groupingBy(Employee::getName)));

		map.forEach((k, v) -> {
			System.out.println(k + " = " + v);
			v.forEach((i, j) -> {
				System.out.println(i + " = " + j);
			});
		});
	}

Collectors.groupingBy() 分组之按月分组

//根据日期字段的 yyyy-MM 进行分组
Map<String, List<SomeEntity>> monthMap = someEntityList.stream().collect(Collectors.groupingBy(p -> cn.hutool.core.date.DateUtil.format(p.getOrderTime(), "yyyy-MM")));

自定义Distinct对结果去重

功能代码

/**
	 * 使用java8 stream groupingBy操作, 基于Distinct 去重数据
	 */
	public void groupingByDistinct() {
		List<Employee> list = employees.stream().filter(distinctByKey(Employee :: getCity))
				.collect(Collectors.toList());;

		list.stream().forEach(item->{
			System.out.println("city = " + item.getCity());
		});
		
		
	}

	/**
	 * 自定义重复key 规则
	 * @param keyExtractor
	 * @return
	 */
	private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
		Set<Object> seen = ConcurrentHashMap.newKeySet();
		return t -> seen.add(keyExtractor.apply(t));
	}
完整源代码:
package com.stream;
​
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
​
/**
 * Java 8 Stream 之groupingBy 分组讲解
 * 
 * @author zzg
 *
 */
public class Java8GroupBy {
​
    List<Employee> employees = new ArrayList<Employee>();
​
    /**
     * 数据初始化
     */
    public void init() {
        List<String> citys = Arrays.asList("湖南", "湖北", "江西", "广西 ");
        for (int i = 0; i < 10; i++) {
            Random random = new Random();
            Integer index = random.nextInt(4);
            Employee employee = new Employee(citys.get(index), "姓名" + i, (random.nextInt(4) * 10 - random.nextInt(4)),
                    (random.nextInt(4) * 1000 - random.nextInt(4)));
            employees.add(employee);
        }
    }
​
    /**
     * 使用java8 stream groupingBy操作,按城市分组list
     */
    public void groupingByCity() {
        Map<String, List<Employee>> map = employees.stream().collect(Collectors.groupingBy(Employee::getCity));
​
        map.forEach((k, v) -> {
            System.out.println(k + " = " + v);
        });
    }
​
    /**
     * 使用java8 stream groupingBy操作,按城市分组list统计count
     */
    public void groupingByCount() {
        Map<String, Long> map = employees.stream()
                .collect(Collectors.groupingBy(Employee::getCity, Collectors.counting()));
​
        map.forEach((k, v) -> {
            System.out.println(k + " = " + v);
        });
    }
​
    /**
     * 使用java8 stream groupingBy操作,按城市分组list并计算分组年龄平均值
     */
    public void groupingByAverage() {
        Map<String, Double> map = employees.stream()
                .collect(Collectors.groupingBy(Employee::getCity, Collectors.averagingInt(Employee::getAge)));
​
        map.forEach((k, v) -> {
            System.out.println(k + " = " + v);
        });
    }
​
    /**
     * 使用java8 stream groupingBy操作,按城市分组list并计算分组销售总值
     */
    public void groupingBySum() {
        Map<String, Long> map = employees.stream()
                .collect(Collectors.groupingBy(Employee::getCity, Collectors.summingLong(Employee::getAmount)));
​
        map.forEach((k, v) -> {
            System.out.println(k + " = " + v);
        });
​
        // 对Map按照分组销售总值逆序排序
        Map<String, Long> sortedMap = new LinkedHashMap<>();
        map.entrySet().stream().sorted(Map.Entry.<String, Long> comparingByValue().reversed())
    .forEachOrdered(e -> sortedMap.put(e.getKey(), e.getValue()));
​
sortedMap.forEach((k, v) -> {
System.out.println(k + " = " + v);
    });
    }
​
/**
* 使用java8 stream groupingBy操作,按城市分组list并通过join操作连接分组list中的对象的name 属性使用逗号分隔
*/
public void groupingByString() {
Map<String, String> map = employees.stream().collect(Collectors.groupingBy(Employee::getCity,
Collectors.mapping(Employee::getName, Collectors.joining(", ", "Names: [", "]"))));
​
map.forEach((k, v) -> {
System.out.println(k + " = " + v);
    });
    }
​
/**
* 使用java8 stream groupingBy操作,按城市分组list,将List转化为name的List
*/
public void groupingByList() {
Map<String, List<String>> map = employees.stream().collect(
Collectors.groupingBy(Employee::getCity, Collectors.mapping(Employee::getName, Collectors.toList())));
​
map.forEach((k, v) -> {
System.out.println(k + " = " + v);
v.stream().forEach(item -> {
System.out.println("item = " + item);
    });
    });
    }
​
/**
* 使用java8 stream groupingBy操作,按城市分组list,将List转化为name的Set
*/
public void groupingBySet() {
Map<String, Set<String>> map = employees.stream().collect(
Collectors.groupingBy(Employee::getCity, Collectors.mapping(Employee::getName, Collectors.toSet())));
​
map.forEach((k, v) -> {
System.out.println(k + " = " + v);
v.stream().forEach(item -> {
System.out.println("item = " + item);
    });
    });
    }
​
/**
* 使用java8 stream groupingBy操作,通过Object对象的成员分组List
*/
public void groupingByObject() {
Map<Manage, List<Employee>> map = employees.stream().collect(Collectors.groupingBy(item -> {
return new Manage(item.getName());
    }));
​
map.forEach((k, v) -> {
System.out.println(k + " = " + v);
    });
    }
​
/**
* 使用java8 stream groupingBy操作, 基于city 和name 实现多次分组
*/
public void groupingBys() {
Map<String, Map<String, List<Employee>>> map = employees.stream()
    .collect(Collectors.groupingBy(Employee::getCity, Collectors.groupingBy(Employee::getName)));
​
map.forEach((k, v) -> {
System.out.println(k + " = " + v);
v.forEach((i, j) -> {
System.out.println(i + " = " + j);
    });
    });
    }
​
/**
* 使用java8 stream groupingBy操作, 基于Distinct 去重数据
*/
public void groupingByDistinct() {
List<Employee> list = employees.stream().filter(distinctByKey(Employee :: getCity))
    .collect(Collectors.toList());;
​
list.stream().forEach(item->{
System.out.println("city = " + item.getCity());
    });


    }
​
/**
* 自定义重复key 规则
* @param keyExtractor
* @return
*/
private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Set<Object> seen = ConcurrentHashMap.newKeySet();
return t -> seen.add(keyExtractor.apply(t));
    }
​
public static void main(String[] args) {
// TODO Auto-generated method stub
Java8GroupBy instance = new Java8GroupBy();
instance.init();
instance.groupingByCity();
instance.groupingByCount();
instance.groupingByAverage();
instance.groupingBySum();
instance.groupingByString();
instance.groupingByList();
instance.groupingBySet();
instance.groupingByObject();
instance.groupingBys();
instance.groupingByDistinct();
​
    }
​
class Employee {
private String city;
private String name;
private Integer age;
private Integer amount;
​
public String getCity() {
return city;
    }
​
public void setCity(String city) {
this.city = city;
    }
​
public String getName() {
return name;
    }
​
public void setName(String name) {
this.name = name;
    }
​
public Integer getAge() {
return age;
    }
​
public void setAge(Integer age) {
this.age = age;
    }
​
public Integer getAmount() {
return amount;
    }
​
public void setAmount(Integer amount) {
this.amount = amount;
    }
​
public Employee(String city, String name, Integer age, Integer amount) {
super();
this.city = city;
this.name = name;
this.age = age;
this.amount = amount;
    }
​
public Employee() {
super();
    }
    }
​
class Manage {
private String name;
​
public String getName() {
return name;
    }
​
public void setName(String name) {
this.name = name;
    }
​
public Manage(String name) {
super();
this.name = name;
    }
​
public Manage() {
super();
    }
    }
​
}

 

标签:Stream,stream,Collectors,map,--,groupingBy,分组,public
From: https://www.cnblogs.com/jasonBin/p/17410880.html

相关文章

  • HTB靶场之Busqueda
    准备:攻击机:虚拟机kali和win10(常规操作就直接用本机win10来操作了)。靶机:Inject,htb网站:https://www.hackthebox.com/,靶机地址:https://app.hackthebox.com/machines/Busqueda。知识点:命令执行、敏感信息发现。备注:这个说难也难说简单也是很简单,如果要通过命令执行来进行shell反弹......
  • 【ⓂMySQL】行级锁(索引项加锁)
    InnoDB行锁是通过给索引上的索引项加锁来实现的。所以,只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁。其他注意事项:在不通过索引条件查询的时候,InnoDB使用的是表锁,而不是行锁。由于MySQL的行锁是针对索引加的锁,不是针对记录加的锁,所以即使是访问不同行的记......
  • 5月18日周四
    计划删减代码,把它变成自己的,准备答辩学习前端知识angular框架,html语法扎实的学,css,JavaScript学习后端框架,Java语言学扎实点知道接口怎么回事,尝试或明白一个接口怎么写,接口调试是怎么实现的解决配置文件中resources中的几千个报错,不解决,无意义要搞明白数据库中的字段......
  • 2023冲刺国赛模拟4
    A.xorontree操作分块,每\(Q/B\)次遍历整棵树,每个询问需要特殊查询\(B\)个复杂度\(\frac{Q}{B}nlog+QB\)大力卡常能过code#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;typedefunsignedlonglongull;typedefpair<int,int>pii;in......
  • Redis 在windows 下安装使用
    管理界面: Release2022.5·lework/RedisDesktopManager-Windows(github.com)redis服务:发布·特波拉多夫斯基/雷迪斯(github.com)验证redis服务是否安装完成,和配置密码redis-cliconfigsetrequirepass密码auth密码 ......
  • Java中的字符串
    目录一、简介二、字符串定义2.1直接定义字符串2.2通过使用String类的构造方法来创建字符串三、如何使用JavaAPI帮助文档3.1帮助文档下载地址3.2帮助文档使用3.2中文帮助文档四、String字符串和int、double、float的相互转换4.1String转int4.2String转Double、Flo......
  • protoBuf 实现客户端与服务端
    转载请注明出处:1.定义消息格式 在src/main/proto目录下创建person.proto文件,并定义消息格式,例如:syntax="proto3";packageexample;messagePerson{stringname=1;int32age=2;repeatedstringinterests=3;}这个文件定义了一个名为Pers......
  • 11-Request&Response
    1,Request和Response的概述Request是请求对象,Response是响应对象。这两个对象在我们使用Servlet的时候有看到:此时,我们就需要思考一个问题request和response这两个参数的作用是什么?request:获取请求数据浏览器会发送HTTP请求到后台服务器[Tomcat]HTTP的请......
  • Spring循环依赖那些事儿(含Spring详细流程图)
    本篇不仅仅是介绍Spring循环依赖的原理,而且给出Spring不能支持的循环依赖场景与案例,对其进行详细解析,同时给出解决建议与方案,以后出现此问题可以少走弯路。背景1、循环依赖异常信息应用时间时间久应用多人同时并行开发应用保证迭代进度经常出......
  • MongoDB-01
    MongoDB官方文档:https://docs.mongodb.com/中文文档:https://www.mongodb.org.cn/mongoDB的生态、理念非常先进而且成熟、但是mongoDB不仅有开源版本,还有企业版本。所以有部分公司比较担心,哪天无法使用mongoDB了,所以也会产生一些替代产品。DynamoDB:AWSSequoiaDB:巨杉数......