如何在Java ArrayList中合并相同ID的对象并保留唯一实例?
合并同ID的Java对象列表
你的现有代码只是将每个Person的position列表合并,但没有移除重复的同ID对象,反而因为遍历原列表时包含当前对象,导致第二个Person的position出现重复。要实现合并为单个同ID对象,核心思路是先按ID分组,再对每组内的对象进行属性合并。
解决方案代码
import java.time.LocalDate; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class PersonMergeExample { public static void main(String[] args) { Person person1 = new Person(1, 470, new ArrayList<>(Arrays.asList(new Position(45, LocalDate.now()), new Position(42, LocalDate.now())))); Person person2 = new Person(1, 320, new ArrayList<>(Arrays.asList(new Position(35, LocalDate.now())))); List<Person> list = new ArrayList<>(); list.add(person1); list.add(person2); // 按ID分组,合并每组内的Person对象 Map<Integer, Person> mergedMap = list.stream() .collect(Collectors.toMap( Person::getId, // 分组键:ID person -> person, // 初始值:当前对象 (existingPerson, newPerson) -> { // 合并position列表 existingPerson.getPosition().addAll(newPerson.getPosition()); // 处理contrac字段:这里示例取第一个对象的值,也可以改成求和/取最大值等逻辑 // existingPerson.setContrac(existingPerson.getContrac() + newPerson.getContrac()); return existingPerson; } )); // 转换为列表 List<Person> mergedList = new ArrayList<>(mergedMap.values()); // 输出结果 mergedList.forEach(System.out::println); } // 规范后的Person类 static class Person { private int id; private int contrac; private List<Position> position; public Person(int id, int contrac, List<Position> position) { this.id = id; this.contrac = contrac; this.position = position; } public int getId() { return id; } public int getContrac() { return contrac; } public void setContrac(int contrac) { this.contrac = contrac; } public List<Position> getPosition() { return position; } public void setPosition(List<Position> position) { this.position = position; } @Override public String toString() { return "person{id=" + id + ", contrac=" + contrac + ", position=" + position + "}"; } } // 规范后的Position类(Java类名首字母大写) static class Position { private int id; private LocalDate bd; public Position(int id, LocalDate bd) { this.id = id; this.bd = bd; } @Override public String toString() { return "position{id=" + id + ", bd=" + bd + "}"; } } }
代码说明
- 分组逻辑:使用
Collectors.toMap按Person的ID作为键分组,当遇到重复ID时,执行自定义的合并逻辑。 - 属性合并:
- 将新对象的
position列表全部追加到已有对象的position集合中; - 对于
contrac字段,示例中保留第一个对象的数值,你可以根据业务需求修改为求和、取最大值等逻辑(代码中注释了求和的写法)。
- 将新对象的
- 结果转换:将合并后的Map值转换为List,得到最终的合并结果。
执行上述代码后,输出结果会是单个同ID的Person对象,包含所有position:
person{id=1, contrac=470, position=[position{id=45, bd=2023-04-14}, position{id=42, bd=2023-04-14}, position{id=35, bd=2023-04-14}]}
内容的提问来源于stack exchange,提问作者ark
相关产品推荐
相关产品推荐

