对象 属性 的两个列表的交集
Intersection of two lists by object property
如果我有两个对象列表,我可以找到交集如下:
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());
有没有类似的方法根据MyObject
的id
字段求交集?我无法重写 equals 方法。
是:
List<MyObject> intersect =
list1.stream()
.filter(obj1 -> list2.stream().map(MyObject::getId).anyMatch(id -> id.equals(obj1.getId()))
.collect(Collectors.toList());
当然,如果两个具有相同id的MyObject
实例被认为是相同的,你可以实现一个equals
方法,returns true
当且仅当id是一样的,那你原码就够了。
你可以试试这个方法。但我认为这对性能没有好处:
List<MyObject> intersect = list1.stream()
.filter(l1 -> list2.stream().anyMatch(l2 -> l2.id.equals(l1.id)))
.collect(Collectors.toList());
与上面 Eran 的回答类似,但您可以先将 ID 拉出到一个单独的集合中,但效率可能稍高一些:
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 + 列表 2)
将 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());
如果我有两个对象列表,我可以找到交集如下:
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());
有没有类似的方法根据MyObject
的id
字段求交集?我无法重写 equals 方法。
是:
List<MyObject> intersect =
list1.stream()
.filter(obj1 -> list2.stream().map(MyObject::getId).anyMatch(id -> id.equals(obj1.getId()))
.collect(Collectors.toList());
当然,如果两个具有相同id的MyObject
实例被认为是相同的,你可以实现一个equals
方法,returns true
当且仅当id是一样的,那你原码就够了。
你可以试试这个方法。但我认为这对性能没有好处:
List<MyObject> intersect = list1.stream()
.filter(l1 -> list2.stream().anyMatch(l2 -> l2.id.equals(l1.id)))
.collect(Collectors.toList());
与上面 Eran 的回答类似,但您可以先将 ID 拉出到一个单独的集合中,但效率可能稍高一些:
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 + 列表 2)
将 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());