利用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>`。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

懒鱼七忆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值