如何使用Java Streams简化同ID对象合并与列表类型转换
问题解答
你当前的实现存在两个明显问题:一是需要二次遍历全量列表,时间复杂度为O(n²),数据量较大时性能差;二是在Stream的map操作中修改外部ImprovedCustomer对象的属性,存在副作用,使用并行流时会出现线程安全问题。
可以直接使用JDK Stream提供的groupingBy分组收集器实现需求,仅需一次主遍历即可完成转换,逻辑更简洁也更符合函数式编程规范。
实现代码
如果需要保持和样例一致的输出顺序(按id首次出现的顺序排列),可以指定LinkedHashMap作为分组的Map容器,代码如下:
import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.stream.Collectors; public class App { public static void main(String[] args) { List<Customer> list = new ArrayList<>(); list.add(new Customer(1, "jon", "fiat", "black")); list.add(new Customer(2, "din", "ford", "yellow")); list.add(new Customer(1, "jon", "benz", "white")); list.add(new Customer(1, "jon", "volvo", "red")); list.add(new Customer(3, "fin", "volvo", "black")); list.add(new Customer(3, "fin", "fiat", "green")); list.add(new Customer(4, "lara", "bmw", "red")); list.add(new Customer(5, "tina", "toyota", "white")); list.add(new Customer(5, "tina", "fiat", "yelow")); list.add(new Customer(6, "bogi", "benz", "black")); // 核心转换逻辑 List<ImprovedCustomer> improvedCustomers = list.stream() .collect(Collectors.groupingBy( Customer::getId, LinkedHashMap::new, // 保证分组顺序和id首次出现顺序一致 Collectors.collectingAndThen(Collectors.toList(), sameIdCustomers -> { Customer firstCus = sameIdCustomers.get(0); List<Car> cars = sameIdCustomers.stream() .map(c -> new Car(c.getCarType(), c.getColor())) .collect(Collectors.toList()); return new ImprovedCustomer(firstCus.getId(), firstCus.getName(), cars); }) )) .values() .stream() .collect(Collectors.toList()); } // 原有Customer、Car、ImprovedCustomer类定义无需修改 }
逻辑说明
- 核心逻辑是按
id对原始Customer列表做分组,同一id的所有客户数据会被聚合到同一个列表中 - 分组过程中通过
collectingAndThen直接对同组数据做转换:同一id对应的name固定,直接取同组第一个元素的id和name即可,再遍历同组元素转成Car列表,直接构造出完整的ImprovedCustomer对象 - 最后取出分组Map中所有的value,就是最终需要的
ImprovedCustomer列表 - 如果不需要保持输出顺序,可以去掉
groupingBy参数中的LinkedHashMap::new,默认使用HashMap存储分组结果性能略高,但无法保证输出顺序和原列表id出现顺序一致;保留该参数时输出结果和你给出的样例顺序完全匹配 - 整个逻辑没有嵌套遍历全量列表的操作,时间复杂度为O(n),性能优于原有实现,同时不存在修改外部对象的副作用,并行执行也不会有线程安全问题。
内容的提问来源于stack exchange,提问作者Jix
相关产品推荐
相关产品推荐

