为了账号安全,请及时绑定邮箱和手机立即绑定

两个列表按对象属性的交集

两个列表按对象属性的交集

慕工程0101907 2023-05-10 13:58:49
如果我有两个对象列表,我可以按如下方式找到交集:public class MyObject {     String id;     String someField;     String someOtherField;}List<MyObject> list1;List<MyObject> list2;List<MyObject> intersect = list1.stream()                           .filter(list2::contains)                           .collect(Collectors.toList());id是否有类似的方法可以根据的领域找到交集MyObject?我无法覆盖 equals 方法。
查看完整描述

4 回答

?
杨魅力

TA贡献1811条经验 获得超5个赞

与上面 Eran 的回答类似,但效率可能稍高一些,您可以先将 ID 拉出到一个单独的 Set 中:

Set<String> ids = list2.stream().map(obj -> obj.id).collect(Collectors.toSet());

List<MyObject> intersect = list1.stream()
    .filter(obj -> ids.contains(obj.id))
    .collect(Collectors.toList());

这会更有效的原因是,对于每个项目,list1您可以确定 ID 是否在list2O(1) 时间内,因此总体而言,您的运行时间为 O(list1 + list2)


查看完整回答
反对 回复 2023-05-10
?
函数式编程

TA贡献1807条经验 获得超9个赞

您可以尝试这种方法。但我认为这对性能没有好处:

List<MyObject> intersect = list1.stream()
                       .filter(l1 -> list2.stream().anyMatch(l2 -> l2.id.equals(l1.id)))
                       .collect(Collectors.toList());


查看完整回答
反对 回复 2023-05-10
?
POPMUISE

TA贡献1765条经验 获得超5个赞

是的:

List<MyObject> intersect =
    list1.stream()
         .filter(obj1 -> list2.stream().map(MyObject::getId).anyMatch(id -> id.equals(obj1.getId()))
         .collect(Collectors.toList());

当然,如果两个MyObject具有相同id的实例被认为是相同的,你可以实现一个当且仅当id相同时equals返回的方法true,然后你的原始代码就足够了。



查看完整回答
反对 回复 2023-05-10
?
哔哔one

TA贡献1854条经验 获得超8个赞

将 提取ids到 a Set,以便尽可能快地进行查找:

Set<String> inclusionsSet = list2.stream().map(a -> a.id()).collect(Collectors.toSet());

List<String> intersection = list1.stream().filter(a -> inclusionsSet.contains(a)).collect(Collectors.toList());



查看完整回答
反对 回复 2023-05-10
  • 4 回答
  • 0 关注
  • 135 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信