You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中如何按相同属性值合并两个存储对象的ArrayList

问题描述

现有两个ArrayList:

  • 第一个存储学生基础信息,每个对象包含id、name、city三个属性
  • 第二个存储学生成绩信息,每个对象包含id、marks、grade三个属性
    需要以两个列表共有的id字段为匹配依据,将对应的对象合并为同时包含学生基础信息和成绩信息的新对象,最终得到合并后的列表。

示例数据

// 学生基础信息
[
        {
            "id": 1,
            "name": "sam",
            "city": "Chennai"
           
        },
        {
            "id": 2,
            "name": "peter",
            "city": "Chennai"
            
        }
    ]
// 学生成绩信息
[
        {
            "id": 1,
            "marks": 95,
            "grade": "A"
           
        },
        {
            "id": 2,
            "marks":63,
            "grade": "B"
            
        }
    ]
// 期望输出
[
        {
            "id": 1,
            "name": "sam",
            "city": "Chennai",
            "marks": 95,
            "grade": "A"
           
        },
        {
            "id": 2,
            "name": "peter",
            "city": "Chennai",
            "marks":63,
            "grade": "B"
            
        }
    ]

原JS实现代码:

async mergeData(data1, data2, key) {
    const result = data1.map(a =>
      Object.assign({}, a,
        data2.find(b => b[key] === a[key])
      )
    )
    return result
}
Java实现方案

1. 定义对应实体类

使用Lombok的@Data注解简化getter、setter代码,无Lombok的场景手动补充对应方法即可。

// 学生基础信息实体
import lombok.Data;
@Data
public class StudentDetail {
    private Integer id;
    private String name;
    private String city;
}
// 学生成绩信息实体
import lombok.Data;
@Data
public class StudentGrade {
    private Integer id;
    private Integer marks;
    private String grade;
}
// 合并后的学生信息实体
import lombok.Data;
@Data
public class StudentVO {
    private Integer id;
    private String name;
    private String city;
    private Integer marks;
    private String grade;

    public StudentVO(StudentDetail detail, StudentGrade grade) {
        this.id = detail.getId();
        this.name = detail.getName();
        this.city = detail.getCity();
        if (grade != null) {
            this.marks = grade.getMarks();
            this.grade = grade.getGrade();
        }
    }
}

2. 合并逻辑实现

优先将成绩列表转为ID为key的Map,将时间复杂度控制在O(n+m),避免双重循环,性能远高于JS中原find的遍历匹配逻辑,更适合大数据量场景。

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

public class StudentMergeService {
    public List<StudentVO> merge(List<StudentDetail> detailList, List<StudentGrade> gradeList) {
        // 构建ID和成绩的映射关系
        Map<Integer, StudentGrade> gradeIdMap = gradeList.stream()
                .collect(Collectors.toMap(StudentGrade::getId, item -> item));
        
        // 遍历基础信息列表匹配成绩,生成合并后的对象
        return detailList.stream()
                .map(detail -> new StudentVO(detail, gradeIdMap.get(detail.getId())))
                // 若需要过滤无成绩的学生,放开下面这行注释
                // .filter(vo -> vo.getMarks() != null)
                .collect(Collectors.toList());
    }
}

内容的提问来源于stack exchange,提问作者monica_s

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 03:57:00