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

时间:2019-08-01 08:26:42

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

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

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的{​​{1}}字段来找到交点?我无法覆盖equals方法。

4 个答案:

答案 0 :(得分:7)

与上述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是否在O(1)时间中在list2中,因此总体上您的运行时为O(list1 + list2 )

答案 1 :(得分:3)

是:

$pattern = "/<p[^>]*><\\/p[^>]*>/"; 
preg_replace($pattern,'',get_the_content());

当然,如果两个具有相同ID的List<MyObject> intersect = list1.stream() .filter(obj1 -> list2.stream().map(MyObject::getId).anyMatch(id -> id.equals(obj1.getId())) .collect(Collectors.toList()); 实例被认为是相同的,则可以实现一个MyObject方法,当且仅当ID相同时才返回equals,并且那么您的原始代码就足够了。

答案 2 :(得分:2)

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

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

答案 3 :(得分:0)

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