Java8_stream_集合对象属性的合并

Java8_stream_集合对象属性的合并

举例:

在实际的业务处理中,我们经常会碰到需要合并同一个集合内相同属性对象的情况, 需要对一个List中的对象进行唯一值属性去重,属性求和。

业务范例:

// 统计每个学生的 总分

Student(name=张三, subject=数学, grade=92.5);
Student(name=张三, subject=语文, grade=80.0);
Student(name=李四, subject=数学, grade=88.5);
Student(name=李四, subject=语文, grade=90.5);
Student(name=王五, subject=数学, grade=100.0);
Student(name=王五, subject=语文, grade=60.0);

 

期望结果:

Student(name=李四, subject=语文/数学, grade=179.0)
Student(name=张三, subject=语文/数学, grade=172.5)
Student(name=王五, subject=语文/数学, grade=160.0)

 

思路:

  1. list做循环求和,去重

  2. Java8的流进行处理

 

代码:

复制代码
import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Test {
    public static void main(String[] args) {
        List<Student> list1 = initData();
        List<Student> list2 = initData();
        List<Student> list3 = initData();

        // 方法一: list做循环求和,去重
        List<Student> students1 = method01(list1);
        students1.forEach(System.out::println);

        System.out.println("====================================");

        // 方法二: Java8的流进行处理
        List<Student> students2 = method02(list2);
        students2.forEach(System.out::println);

        System.out.println("====================================");

        // 方法三
        List<Student> students3 = method03(list3);
        students3.forEach(System.out::println);
    }

    // 方法一: list做循环求和,去重
    private static List<Student> method01(List<Student> list) {
        Map<String, Student> map = new HashMap<>();
        list.stream().forEach(a -> {
                    Student last = map.get(a.getName());
                    if(null != last){
                        a.setGrade(a.getGrade() + last.getGrade());
                        a.setSubject(a.getSubject() + "/" + last.getSubject());
                    }
                    map.put(a.getName(), a);
                });
        return map.values().stream().collect(Collectors.toList());
    }

    // 方法二: Java8的流进行处理
    private static List<Student> method02(List<Student> list) {
        List<Student> result = list.stream().collect(Collectors.toMap(Student::getName, a -> a, (o1, o2) -> {
            o1.setGrade(o1.getGrade() + o2.getGrade());
            o1.setSubject(o1.getSubject() + "/" + o2.getSubject());
            return o1;
        })).values().stream().collect(Collectors.toList());
        return result;
    }

    // 方法三
    private static List<Student> method03(List<Student> list) {
        List<Student> students = new ArrayList<>();
        list.stream().collect(Collectors.groupingBy(o -> o.getName(), Collectors.toList())).forEach(
                (id, transfer) -> {
                    transfer.stream().reduce((a, b) ->
                            new Student(a.getName(), a.getSubject() + "/" + b.getSubject(), a.getGrade() + b.getGrade())).ifPresent(students::add);
                }
        );
        return students;
    }

    private static List<Student> initData(){
        List<Student> students =  new ArrayList<>();
        students.add(new Student("张三", "数学", 92.5));
        students.add(new Student("张三", "语文", 80));
        students.add(new Student("李四", "数学", 88.5));
        students.add(new Student("李四", "语文", 90.5));
        students.add(new Student("王五", "数学", 100));
        students.add(new Student("王五", "语文", 60));
        return students;
    }
}

@Data
@AllArgsConstructor
class Student {
    private String name; // 学生名称
    private String subject; // 学科
    private double grade; // 成绩
}
复制代码

 

执行结果:

复制代码
Student(name=李四, subject=语文/数学, grade=179.0)
Student(name=张三, subject=语文/数学, grade=172.5)
Student(name=王五, subject=语文/数学, grade=160.0)
====================================
Student(name=李四, subject=数学/语文, grade=179.0)
Student(name=张三, subject=数学/语文, grade=172.5)
Student(name=王五, subject=数学/语文, grade=160.0)
====================================
Student(name=李四, subject=数学/语文, grade=179.0)
Student(name=张三, subject=数学/语文, grade=172.5)
Student(name=王五, subject=数学/语文, grade=160.0)
复制代码

 

 

posted @   梅子猪  阅读(4173)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
点击右上角即可分享
微信分享提示