【问题标题】:Intersection of two lists by object property对象属性的两个列表的交集
【发布时间】:2019-08-01 08:26:42
【问题描述】:

如果我有两个对象列表,我可以如下找到交集:

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());

有没有类似的方法可以根据MyObjectid字段找到交集?我无法覆盖 equals 方法。

【问题讨论】:

    标签: java list java-8 java-stream intersection


    【解决方案1】:

    与上面 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 中的每个项目,您可以在 O(1) 时间内确定 ID 是否在 list2 中,因此总体而言,您的运行时间为 O(list1 + list2)

    【讨论】:

      【解决方案2】:

      是的:

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

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

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          【解决方案4】:

          ids 提取为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());
          

          【讨论】:

            猜你喜欢
            • 2018-04-06
            • 1970-01-01
            • 2020-07-24
            • 2012-02-12
            • 1970-01-01
            • 1970-01-01
            • 2021-05-08
            • 1970-01-01
            • 2020-03-31
            相关资源
            最近更新 更多