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岁的人员。

阅读剩余 57%

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

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

相关文章

  • PHP中mysql_field_type()函数用法

    当使用PHP操作MySQL数据库时,mysql_field_type()函数将返回给定列的类型。以下是该函数的使用方法: 语法: string mysql_field_type ( resource $result , int $field_offset ) 参数: $result:MySQL 查询结果资源,通过函数 mysql_query() 成功返回的资…

    other 2023年6月25日
    00
  • Python实现一个服务器监听多个客户端请求

    下面是Python实现一个服务器监听多个客户端请求的完整攻略: 1. 创建一个基于TCP协议的服务器 首先,我们需要创建一个基于TCP协议的服务器来监听客户端请求。Python提供了socket模块来处理网络通信,我们可以使用其创建一个TCP服务器。以下是创建TCP服务器的代码示例: import socket host = ‘127.0.0.1’ # 服务…

    other 2023年6月27日
    00
  • 浅谈SpringBoot主流读取配置文件三种方式

    下面我来详细讲解“浅谈SpringBoot主流读取配置文件三种方式”的完整攻略。 1. 前言 Spring Boot 应用程序支持从多种文件格式中读取配置数据,如 .properties, .yaml, .xml 等。Spring Boot 配置机制是注重选择与约定优于配置的,这意味着我们可以轻松地读取和管理我们的应用程序中的配置数据。 本文将探讨 Spri…

    other 2023年6月25日
    00
  • C语言数组的各种操作梳理

    C语言数组的各种操作梳理 1. 定义数组 定义数组需要指定数组的类型、名称和元素个数,语法如下: type arrayName[arraySize]; 示例1:定义一个长度为10的整型数组 int numbers[10]; 示例2:定义一个长度为5的double类型数组 double scores[5]; 2. 数组初始化 数组初始化可以在定义时进行,通过一…

    other 2023年6月25日
    00
  • 浅谈C/C++中的static与extern关键字的使用详解

    浅谈C/C++中的static与extern关键字的使用详解 1. static关键字 在C/C++中,static关键字可以用于不同的上下文中,具有不同的含义和作用。 1.1 静态变量 在函数内部使用static关键字声明的变量称为静态变量。静态变量与普通变量的区别在于,静态变量的生命周期延长到整个程序的执行期间,而不是仅在函数调用时存在。 示例代码: #…

    other 2023年7月29日
    00
  • .Net笔记:System.IO之windows文件操作的深入分析

    下面是“.Net笔记:System.IO之windows文件操作的深入分析”的完整攻略。 简介 System.IO 命名空间提供了一组用于对文件、文件夹、和目录进行操作的类和接口。本篇笔记将对 System.IO 命名空间的部分重要类和方法进行深入分析,并结合实际例子进行讲解。 FileStream 类 FileStream 类表示的是一个文件流类,可以用来…

    other 2023年6月26日
    00
  • Spring中获取Bean对象的三种注入方式与两种注入方法详解

    Spring中获取Bean对象的三种注入方式与两种注入方法详解 在Spring框架中,我们可以通过三种不同的方式来获取Bean对象,即构造函数注入、Setter方法注入和字段注入。同时,Spring还提供了两种注入方法,即XML配置文件注入和注解注入。 1. 构造函数注入 构造函数注入是通过调用Bean对象的构造函数来实现依赖注入。在Spring中,我们可以…

    other 2023年8月6日
    00
  • Anaconda安装以及修改环境默认位置图文教程

    以下是详细讲解“Anaconda安装以及修改环境默认位置图文教程”的完整攻略。 Anaconda安装教程 Step 1 下载Anaconda 打开Anaconda官网(https://www.anaconda.com/products/individual),选择符合本地系统版本的Anaconda,下载对应安装包即可。 示例1:如果本地系统是Windows系…

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