Java 8中如何根据id字段获取两个Person列表的匹配子集?
最优解决方案:利用Stream API + HashSet 实现高效匹配
这是个很典型的集合匹配场景,在Java 8里我们可以通过先预存匹配标识+Stream过滤的组合来实现最优性能的匹配,下面具体拆解实现思路和代码:
核心思路:用HashSet降低匹配成本
直接嵌套遍历两个列表做匹配的时间复杂度是O(n*m),当数据量变大时会很慢。我们可以先把ages里的所有id提取到HashSet中(HashSet的contains()方法是O(1)时间复杂度),再用Stream过滤persons,这样整体时间复杂度能降到O(n+m),效率提升非常明显。
具体代码实现
1. 提取ages中的id到HashSet
Set<String> matchedIds = ages.stream() .map(Person::getId) .collect(Collectors.toSet());
2. 过滤persons得到匹配子集
List<Person> result = persons.stream() .filter(person -> matchedIds.contains(person.getId())) .collect(Collectors.toList());
完整可运行示例
import lombok.Builder; import lombok.Getter; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @Getter @Builder class Person { private String id; private String name; private Integer age; } public class PersonMatchDemo { public static void main(String[] args) { List<Person> persons = new ArrayList<>(); persons.add(Person.builder().id("001").name("alpha").build()); persons.add(Person.builder().id("002").name("beta").build()); persons.add(Person.builder().id("003").name("gamma").build()); List<Person> ages = new ArrayList<>(); ages.add(Person.builder().id("001").age(25).build()); ages.add(Person.builder().id("002").age(40).build()); // 预存需要匹配的id集合 Set<String> matchedIds = ages.stream() .map(Person::getId) .collect(Collectors.toSet()); // 筛选出匹配的Person子集 List<Person> matchedPersons = persons.stream() .filter(p -> matchedIds.contains(p.getId())) .collect(Collectors.toList()); // 打印验证结果 matchedPersons.forEach(p -> System.out.printf("ID: %s, Name: %s%n", p.getId(), p.getName())); // 输出: // ID: 001, Name: alpha // ID: 002, Name: beta } }
补充说明
如果你的需求不仅是筛选子集,还需要把ages里的age属性合并到persons的对应对象中,可以在过滤后再做一步属性赋值,比如:
List<Person> mergedPersons = persons.stream() .filter(p -> matchedIds.contains(p.getId())) .map(p -> { // 找到对应的age对象 Person ageObj = ages.stream() .filter(a -> a.getId().equals(p.getId())) .findFirst() .orElse(null); // 合并属性,这里需要注意Person是不可变类的话要重新build return Person.builder() .id(p.getId()) .name(p.getName()) .age(ageObj != null ? ageObj.getAge() : null) .build(); }) .collect(Collectors.toList());
内容的提问来源于stack exchange,提问作者Abhi Nandan
相关产品推荐
相关产品推荐

