Java中基于指定字段比较两个自定义对象列表并生成新列表
Java Stream实现双列表字段对比筛选
自定义类A的定义
首先先补全自定义类A的代码(包含必要的构造方法、Getter和toString):
class A { private int no; private int age; private int foo; private int bar; public A(int no, int age, int foo, int bar) { this.no = no; this.age = age; this.foo = foo; this.bar = bar; } public int getNo() { return no; } public int getAge() { return age; } public int getFoo() { return foo; } public int getBar() { return bar; } @Override public String toString() { return String.format("A{no=%d, age=%d, foo=%d, bar=%d}", no, age, foo, bar); } }
核心筛选逻辑
为了提升查找效率,先把aList转换成以no为键的Map,再用Stream遍历bList进行筛选:
import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class ListFilterDemo { public static void main(String[] args) { // 示例数据 List<A> aList = Arrays.asList( new A(2, 20, 50, 60), new A(3, 25, 40, 60), new A(4, 40, 10, 20) ); List<A> bList = Arrays.asList( new A(2, 10, 50, 60), new A(3, 25, 50, 60), new A(4, 40, 10, 20) ); // 将aList转成以no为键的Map,O(1)查找效率 Map<Integer, A> aNoMap = aList.stream() .collect(Collectors.toMap(A::getNo, a -> a)); // 筛选符合条件的bList元素 List<A> filteredList = bList.stream() .filter(b -> { A matchedA = aNoMap.get(b.getNo()); // 条件1:no在aList中存在;条件2:age或foo与对应a对象不同 return matchedA != null && (b.getAge() != matchedA.getAge() || b.getFoo() != matchedA.getFoo()); }) .collect(Collectors.toList()); // 输出结果 filteredList.forEach(System.out::println); } }
逻辑说明
- Map转换:把
aList转成Map后,避免了在筛选时每次遍历aList匹配no,大幅提升性能(尤其是列表元素较多时)。 - 筛选条件:
- 先判断当前
b对象的no是否在aList中存在(通过Map查找是否为null); - 若存在,再对比
age或foo字段是否与aList中同no的对象不同,满足任一差异即可保留。
- 先判断当前
运行上述代码后,输出结果与预期一致:
A{no=2, age=10, foo=50, bar=60} A{no=3, age=25, foo=50, bar=60}
内容的提问来源于stack exchange,提问作者Som
相关产品推荐
相关产品推荐

