利用Stream流将取到的对象List<对象>形式数据进行分组统计转变成Map<分组条件,数量统计>形式

简介: 利用Stream流将取到的对象List<对象>形式数据进行分组统计转变成Map<分组条件,数量统计>形式

      举个例子吧,目前的业务需要把取到的数据,进行分组,然后好用另一个方法进行数据处理。

     用到的方法就是 Collectors.groupingBy,Collectors.counting(),  Collectors.reducing()。

    然后,就以下面的为例子,将取到的list集合,将取到的数据以性别分组,以性别为K,以性别数量为v,。

代码示例:
package Lx;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class StreamLiu {
  public static void main(String[] args) {
        // 假设有三个包含对象的list链表
        List<Person> list1 = new ArrayList<>();
        Person person = new Person();
        person.setIdCard("100001");
        person.setName("张三");
        person.setAge("M");
        list1.add(person);
        // 向list1中添加一些Person对象
        List<Person> list2 = new ArrayList<>();
        // 向list2中添加一些Person对象
        Person person2 = new Person();
        person2.setIdCard("100002");
        person2.setName("李四");
        person2.setAge("M");
        list2.add(person2);
        List<Person> list3 = new ArrayList<>();
        // 向list3中添加一些Person对象
        Person person3 = new Person();
        person3.setIdCard("100003");
        person3.setName("赵芳");
        person3.setAge("W");
        list3.add(person3);
        // 将这三个链表合并成一个总的链表
        List<Person> totalList = new ArrayList<>();
        totalList.addAll(list1);
        totalList.addAll(list2);
        totalList.addAll(list3);
        //要求:将totalList转变成以性别为主键,性别数量为value的集合
        /***方法一--start***/
        Map<String, Integer> result =  totalList.stream().collect(Collectors.groupingBy(
            Person::getAge,
                Collectors.reducing(0, e -> 1, Integer::sum)
        ));
        System.out.println("reult "+result);
        /***方法二--start***/
        Map<String, Long> result2 =   totalList.stream().collect(Collectors.groupingBy(
            Person::getAge,
                Collectors.counting()
                ));
        System.out.println("reult "+result);
    }
}
class Person {
    private String idCard;
    // 其他属性和方法
    private String name;
    //性别1男2女
    private String age;
    public String getIdCard() {
        return idCard;
    }
    public void setIdCard(String idCard) {
        this.idCard = idCard;
    }
    // 其他getter和setter方法
    public String getAge() {
    return age;
  }
  public void setAge(String age) {
    this.age = age;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  @Override
    public String toString() {
        return "Person{" +
                "idCard='" + idCard + '\'' +
                // 其他属性
                '}';
    }
}
打印结果:

关键代码分析:
方法一:
/***方法一--start***/
        Map<String, Integer> result =  totalList.stream().collect(Collectors.groupingBy(
            Person::getAge,
                Collectors.reducing(0, e -> 1, Integer::sum)
        ));

 这段代码使用Java 8中的Stream API将一个`List`中的对象按照`Person`对象的`age`属性进行分组,并计算每个分组中的元素个数,并将结果存储在一个`Map`中返回。具体来说,代码中使用了`Collectors.groupingBy`方法和`Collectors.reducing`方法,分别表示对列表进行分组和规约(计算)操作。

以下是详细的解析:

1. `totalList.stream()`:将`totalList`转换为`Stream`对象,以便使用Stream API进行操作。

2. `Collectors.groupingBy(Person::getAge, Collectors.reducing(0, e -> 1, Integer::sum))`:对`totalList`中的元素按照`Person`对象的`age`属性进行分组,并计算每个分组中的元素个数。

   * `Person::getAge` 指定了按照`Person`对象的`age`属性进行分组,即将具有相同`age`属性的元素分为同一组。

   

   * `Collectors.reducing`方法指定每个分组中元素的计算方式。在本例中,将每个分组中的元素规约(计算)为它们数量的和。 具体来说,`Collectors.reducing(0, e -> 1, Integer::sum)`中:

       * `0` 表示初始值,即每个分组的元素数量的初始值为0。

       

       * `e -> 1` 是一个Lambda表达式,表示将每个元素映射为`1`,即对每个元素计数。

       

       * `Integer::sum` 指定了将所有映射为`1`的元素相加的操作,即将每个分组中的元素数量相加。

       

   通过这样的规约操作,将每个分组的元素数量计算出来。

3. 由于`Collectors.groupingBy`方法的返回值为`Map<K,List<V>>`类型,即一个分组名和分组元素列表的映射关系。而在本例中,分组名为`String`类型,表示`Person`对象的`age`属性的取值,元素数量为`Integer`类型,表示每个分组中元素的数量。因此,最终返回的类型为`Map<String, Integer>`。

方法二:(因为方法二value是Long类型,所以直接用Collectors.counting()可以)
/***方法二--start***/
        Map<String, Long> result2 =   totalList.stream().collect(Collectors.groupingBy(
            Person::getAge,
                Collectors.counting()
                ));

这段代码使用Java 8中的Stream API将一个`List`中的对象按照`Person`对象的`age`属性进行分组,并计算每个分组中的元素个数,并将结果存储在一个`Map`中返回。具体来说,代码中使用了`Collectors.groupingBy`方法和`Collectors.counting`方法,分别表示对列表进行分组和计数操作。

以下是详细的解析:

1. `totalList.stream()`:将`totalList`转换为`Stream`对象,以便使用Stream API进行操作。

2. `Collectors.groupingBy(Person::getAge, Collectors.counting())`:对`totalList`中的元素按照`Person`对象的`age`属性进行分组,并计算每个分组中的元素个数。

   * `Person::getAge` 指定了按照`Person`对象的`age`属性进行分组,即将具有相同`age`属性的元素分为同一组。

   

   * `Collectors.counting()` 方法用于计算每个分组中的元素个数。

   

   通过这样的操作,将每个分组的元素数量计算出来。

3. 由于`Collectors.groupingBy`方法的返回值为`Map<K,List<V>>`类型,即一个分组名和分组元素列表的映射关系。而在本例中,分组名为`String`类型,表示`Person`对象的`age`属性的取值,元素数量为`Long`类型,表示每个分组中元素的数量。因此,最终返回的类型为`Map<String, Long>`。

相关文章
|
8月前
|
安全 Java API
【Java性能优化】Map.merge()方法:告别繁琐判空,3行代码搞定统计累加!
在日常开发中,我们经常需要对Map中的值进行累加统计。}else{代码冗长,重复调用get()方法需要显式处理null值非原子操作,多线程下不安全今天要介绍的方法,可以让你用一行代码优雅解决所有这些问题!方法的基本用法和优势与传统写法的对比分析多线程安全版本的实现Stream API的终极优化方案底层实现原理和性能优化建议一句话总结是Java 8为我们提供的Map操作利器,能让你的统计代码更简洁、更安全、更高效!// 合并两个列表});简单累加。
816 0
|
消息中间件 负载均衡 NoSQL
Redis系列学习文章分享---第七篇(Redis快速入门之消息队列--List实现消息队列 Pubsub实现消息队列 stream的单消费模式 stream的消费者组模式 基于stream消息队列)
Redis系列学习文章分享---第七篇(Redis快速入门之消息队列--List实现消息队列 Pubsub实现消息队列 stream的单消费模式 stream的消费者组模式 基于stream消息队列)
346 0
|
供应链 JavaScript 前端开发
深入理解 ECMAScript 2024 新特性:Map.groupBy() 分组操作
ECMAScript 2024 (ES15) 引入了 `Map.groupBy()`,极大简化了数据分组操作。该方法从可迭代对象创建一个 `Map`,根据回调函数生成的键进行分组。适用于按条件、属性或复杂键分组,代码更简洁优雅。相比 `reduce`,它提供了更高的性能和更好的可读性,适合处理大量数据。通过详细案例展示,本文深入剖析了 `Map.groupBy()` 的强大功能及其应用场景。
206 11
ES6中map对象的使用,确实比Object好使哈
ES6中Map对象的使用优势,包括任意类型作为键、直接获取大小、增删查改操作等。Map的键可以是函数、对象、NaN等,支持forEach循环和for...of循环。
192 1
ES6中map对象的使用,确实比Object好使哈
|
JSON 前端开发 JavaScript
json字符串如何转为list对象?
json字符串如何转为list对象?
2062 7
|
TensorFlow 算法框架/工具 Python
从numpy,list对象创建
【8月更文挑战第12天】从numpy,list对象创建。
97 8
|
SQL 关系型数据库 MySQL
INSERT INTO t_a.tableName SELECT * FROM t_b.tableName 如何通过定义一个list对象,包含多个tableName,循环执行前面的sql,用MySQL的语法写
【8月更文挑战第7天】INSERT INTO t_a.tableName SELECT * FROM t_b.tableName 如何通过定义一个list对象,包含多个tableName,循环执行前面的sql,用MySQL的语法写
199 5
|
存储 分布式计算 DataWorks
MaxCompute产品使用合集之要存储用户的下单所有产品,然后查询时要进行产品分组的,一般这种字段要使用ARRAY还是MAP
MaxCompute作为一款全面的大数据处理平台,广泛应用于各类大数据分析、数据挖掘、BI及机器学习场景。掌握其核心功能、熟练操作流程、遵循最佳实践,可以帮助用户高效、安全地管理和利用海量数据。以下是一个关于MaxCompute产品使用的合集,涵盖了其核心功能、应用场景、操作流程以及最佳实践等内容。
|
存储 Java 索引
Java 中 List、Set、Map 和 Queue 之间的区别
【8月更文挑战第22天】
483 0
|
Java
Java list中的对象转为list,list中的对象转为map
Java list中的对象转为list,list中的对象转为map
892 1