Java 8中合并两个List<Foo>并按ID实现元素去重的方法
优雅合并两个列表并保证指定属性唯一的Java 8实现
刚好之前处理过一模一样的需求,用Java 8的Stream API结合Map的键唯一性就能完美解决,代码简洁还符合现代Java的风格。
核心思路是利用Map的键不可重复特性:把Foo的id作为Map的键,这样重复的id会被自动处理,我们只需要指定遇到重复时保留哪个元素就行。
基础实现(默认无序)
如果不关心最终列表的元素顺序,直接用下面的代码:
import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; // ... 你的Foo类定义 List<Foo> listA = getListA(); List<Foo> listB = getListB(); List<Foo> uniqueFoos = Stream.concat(listA.stream(), listB.stream()) .collect(Collectors.toMap( Foo::getId, // 以Foo的id作为Map的键 Function.identity(), // Map的值就是Foo对象本身 (existing, replacement) -> existing // 遇到重复id时,保留已存在的元素(也就是listA里的) )) .values() // 提取Map中所有的Foo对象 .stream() .collect(Collectors.toList());
保持插入顺序的实现
如果需要保留元素的原始顺序(listA的元素在前,listB中不重复的元素紧跟其后),可以指定用LinkedHashMap来存储,它会记住元素的插入顺序:
List<Foo> uniqueFoos = Stream.concat(listA.stream(), listB.stream()) .collect(Collectors.toMap( Foo::getId, Function.identity(), (existing, replacement) -> existing, LinkedHashMap::new // 指定使用LinkedHashMap维持顺序 )) .values() .stream() .collect(Collectors.toList());
调整优先级
如果你的需求是当id重复时保留listB的元素,只需要修改合并函数的返回值:
(existing, replacement) -> replacement // 遇到重复时,用新元素(listB里的)替换旧元素
这样处理后,uniqueFoos里就只会包含所有id唯一的Foo对象啦。
内容的提问来源于stack exchange,提问作者Hatch
相关产品推荐
相关产品推荐

