List集合按某个属性或者字段进行分组的操作

一、背景介绍
在Java中,List是最常用的集合类型之一,它可以存储任何类型的对象,但在实际开发中,我们有时需要按照某种属性或者字段对List中的元素进行分组,这可以通过Java8中新增的Stream API来实现。

二、具体实现步骤

1.创建一个包含多个元素的List集合,例如:

List<Student> students = new ArrayList<>();
students.add(new Student("Tom", "math", 85));
students.add(new Student("Tom", "english", 90));
students.add(new Student("Mary", "math", 92));
students.add(new Student("Mary", "english", 87));

2.使用Stream API对List进行分组,例如按照学生姓名进行分组

Map<String, List<Student>> groupByName = students.stream().collect(Collectors.groupingBy(Student::getName));

这里使用了Stream中的groupingBy()方法来对List进行分组,需要提供一个按照哪个属性分组的条件,该方法会返回一个Map对象,其中键为分组条件,值为List集合,即按照该条件分组后的结果。

3.使用Stream API进一步处理分组结果,例如计算每个分组的平均分

Map<String, Double> avgScoreByName = groupByName.entrySet().stream()
        .collect(Collectors.toMap(Map.Entry::getKey, v -> {
            List<Student> list = v.getValue();
            double sumScore = list.stream().mapToInt(Student::getScore).sum();
            return sumScore / list.size();
        }));

这里使用了Stream中的toMap()方法将分组结果转换成键值对形式,并对每个分组求出平均分。其中,我们使用了EntrySet()方法获取Map中的键值对,并展开进行处理。

三、示例说明

示例一:按照性别对员工进行分组

假设我们有一个Employee类,其中包含了员工的姓名、性别和工资三个属性,现在我们需要按照性别对所有员工进行分组,并统计每个分组的平均工资。

public class Employee {
    private String name;
    private String sex;
    private double salary;

    public Employee(String name, String sex, double salary) {
        this.name = name;
        this.sex = sex;
        this.salary = salary;
    }

    //getter、setter方法
}

List<Employee> employees = new ArrayList<>();
employees.add(new Employee("Tom", "Male", 5000));
employees.add(new Employee("Jane", "Female", 6000));
employees.add(new Employee("John", "Male", 4000));
employees.add(new Employee("Lucy", "Female", 7000));

Map<String, Double> groupBySex = employees.stream().collect(Collectors.groupingBy(Employee::getSex, Collectors.averagingDouble(Employee::getSalary)));

这里我们使用了两级分组,首先按照性别进行分组,然后对每个分组进行平均工资的计算,最终输出结果为:

{Female=6500.0, Male=4500.0}

示例二:按照省份进行多级分组

假设我们有一个Person类,其中包含了人员的姓名、年龄和省份三个属性,现在我们需要按照省份对所有人进行分组,并统计每个省份中不同年龄段的人员数量。

public class Person {
    private String name;
    private int age;
    private String province;

    public Person(String name, int age, String province) {
        this.name = name;
        this.age = age;
        this.province = province;
    }

    //getter、setter方法
}

List<Person> persons = new ArrayList<>();
persons.add(new Person("Tom", 20, "Guangdong"));
persons.add(new Person("Jane", 25, "Guangdong"));
persons.add(new Person("John", 30, "Guangdong"));
persons.add(new Person("Lucy", 35, "Guangxi"));
persons.add(new Person("Steven", 40, "Guangxi"));
persons.add(new Person("Bob", 45, "Guangxi"));

Map<String, Map<Integer, Long>> groupByProvinceAndAge = persons.stream()
        .collect(Collectors.groupingBy(Person::getProvince, Collectors.groupingBy(p -> p.getAge() / 10, Collectors.counting())));

这里我们也使用了两级分组,其中第一级按照省份进行分组,第二级按照年龄段进行分组,并计算每个分组中的人员数量。最终输出结果为:

{
    Guangdong={
        2=1, 
        3=1, 
        4=1
    }, 
    Guangxi={
        3=1, 
        4=2
    }
}

其中,Guangdong省中有2个20~30岁的人员、1个30~40岁的人员和1个40~50岁的人员;Guangxi省中有1个30~40岁的人员和2个40~50岁的人员。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:List集合按某个属性或者字段进行分组的操作 - Python技术站

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • CMD下的网络安全配置方法

    下面是对“CMD下的网络安全配置方法”的完整攻略: 1. 常规基础概念 在 CMD 中进行网络安全设置,需要掌握一些基本的概念: IP地址:设备在网络中的唯一标识。 子网掩码:用于指定一个网络地址的前缀和子网号的长度。 默认网关:当计算机需要访问的网络地址不在本地子网中时,需要通过默认网关来转发。 DNS: Domain Name System,域名解析系统…

    other 2023年6月26日
    00
  • 终于实现samba可写不可删除

    终于实现samba可写不可删除 对于使用 Samba 进行文件共享的用户来说,一般情况下会设置为可读写权限,也就是既可以读取又可以写入文件,这对于家庭共享或小型团体很方便。但是如果需要限制某些用户或组只能写入文件,而不能删除文件,可能就需要修改 Samba 的配置。 修改Samba配置文件 Samba 的配置文件一般是 /etc/samba/smb.conf…

    其他 2023年3月28日
    00
  • MAC上Mysql忘记Root密码或权限错误的快速解决方案

    下面是“MAC上Mysql忘记Root密码或权限错误的快速解决方案”的详细攻略: 步骤一:停止 MySQL 服务。 打开终端,执行以下命令停止 MySQL 服务: sudo /usr/local/mysql/support-files/mysql.server stop 步骤二:进入 MySQL 安全模式 重新启动 MySQL 服务,并进入 MySQL 安全…

    other 2023年6月26日
    00
  • Java基础之不简单的数组

    Java基础之不简单的数组:完整攻略 1. 数组的定义 Java中的数组是一种数据结构,用于存储相同类型的数据。数组定义时需要指定数据类型和长度,数组长度不能被改变。 // 定义int类型长度为3的数组 int[] nums = new int[3]; // 定义String类型长度为2的数组 String[] names = new String[2]; …

    other 2023年6月25日
    00
  • 快速解决低版本Xcode不支持高版本iOS真机调试的问题方法

    快速解决低版本Xcode不支持高版本iOS真机调试的问题方法攻略 如果你的Xcode版本较低,无法支持高版本iOS设备的真机调试,下面是一些解决该问题的方法。 方法一:使用适配工具 有一些第三方工具可以帮助你在低版本的Xcode上进行高版本iOS设备的真机调试。其中一个常用的工具是 ios-deploy。以下是使用该工具的步骤: 打开终端(Terminal)…

    other 2023年8月3日
    00
  • Vim初学者入门指南详解

    Vim是一款强大的文本编辑器,但是对于初学者来说,它的复杂性和怪异的操作方式往往让人望而却步。因此,下面是一份Vim初学者入门指南的详解攻略,以帮助初学者快速上手。 简介 Vim是一款免费、跨平台的文本编辑器,可以在不离开编辑器的情况下对文件进行复杂的编辑。Vim的优点在于它可以通过键盘控制,并且支持多种模式,如普通模式、插入模式、命令行模式等。 安装和基础…

    other 2023年6月26日
    00
  • matlab绘图详解

    MATLAB绘图详解 MATLAB是一种强大的数学软件,它提供了丰富的绘图功能,可以用于绘制各种类型的图表。本攻略将介绍MATLAB中常用的绘图函数和绘图技巧,并提供两个示例说明如何使用这些函数和技巧。 常用绘图函数 plot函数 plot函数用于绘制维线性图。以下是plot函数的语法: plot(x, y) 在上述代码中,x表示x轴上的数据,y表示y轴上的…

    other 2023年5月7日
    00
  • uniapp开发小程序的开发规范总结

    UniApp开发小程序的开发规范总结攻略 1. 项目结构规范 将项目文件按照功能模块进行组织,每个模块包含页面、组件、样式和逻辑代码。 使用合理的命名规范,包括文件名、变量名和函数名,以提高代码的可读性和维护性。 遵循一致的文件命名风格,例如使用小写字母、短横线分隔单词等。 2. 页面规范 每个页面应该有一个独立的文件夹,包含页面的逻辑代码、样式和模板。 页…

    other 2023年9月7日
    00
合作推广
合作推广
分享本页
返回顶部