如何比较不同类型的列表并保留aList中与bList匹配的元素?
解决不同类列表的匹配过滤问题
嗨,我来帮你搞定这个问题!你用retainAll(bList)没效果的原因很简单:AClass和BClass是完全独立的两个类,retainAll()默认会调用对象的equals()方法判断是否相等,不同类的对象永远不会被判定为相等,所以这个方法对你的场景完全不适用。
那该怎么实现只保留aList中与bList匹配的元素呢?核心思路是:先从bList中提取出「匹配的关键特征」,再用这些特征去过滤aList。下面给你两种实用的实现方式:
方式一:用字符串拼接作为匹配键(简单快捷)
如果你的匹配规则是「aid和cname都一致才算匹配」,可以把这两个字段拼接成唯一字符串,存到集合里,再过滤aList:
import java.util.Set; import java.util.stream.Collectors; // 第一步:提取bList中的匹配键集合 Set<String> matchKeys = bList.stream() .map(b -> b.aid + "_" + b.cname) // 用aid+下划线+cname作为唯一标识 .collect(Collectors.toSet()); // 第二步:过滤aList,只保留存在于匹配键集合中的元素 aList = aList.stream() .filter(a -> matchKeys.contains(a.aid + "_" + a.cname)) .collect(Collectors.toList());
方式二:用自定义匹配键类(更优雅健壮)
如果觉得字符串拼接不够严谨(比如字段里可能包含下划线),可以创建一个专门的匹配键类,重写equals()和hashCode()方法:
import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; // 定义内部类作为匹配键,封装用于匹配的字段 private static class MatchKey { private final int aid; private final String cname; public MatchKey(int aid, String cname) { this.aid = aid; this.cname = cname; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; MatchKey matchKey = (MatchKey) o; return aid == matchKey.aid && Objects.equals(cname, matchKey.cname); } @Override public int hashCode() { return Objects.hash(aid, cname); } } // 提取匹配键并过滤aList Set<MatchKey> matchKeys = bList.stream() .map(b -> new MatchKey(b.aid, b.cname)) .collect(Collectors.toSet()); aList = aList.stream() .filter(a -> matchKeys.contains(new MatchKey(a.aid, a.cname))) .collect(Collectors.toList());
灵活调整匹配规则
如果你的匹配规则不是「aid+cname」,比如只需要aid相同,那只需要把提取键的逻辑改成只取aid就行:
Set<Integer> matchAids = bList.stream() .map(b -> b.aid) .collect(Collectors.toSet()); aList = aList.stream() .filter(a -> matchAids.contains(a.aid)) .collect(Collectors.toList());
这样处理后,aList就只会保留和bList匹配的元素啦!
内容的提问来源于stack exchange,提问作者nidhi
相关产品推荐
相关产品推荐

