如何对多个集合进行相交?

问题描述 投票:0回答:4

我有这个清单:

private List<Set<Address>> scanList;

所以我的列表包含多个扫描,如您所见。 每次扫描后,我都会将新的集合添加到列表中。

所有扫描完成后,我只想取出每组中出现的地址并将其放入:

private List<Address> addresses;

Set/TreeSet/HashSet 中是否已经存在这样的东西?

编辑:答案之后,retainAll() 是正确的方法。谢谢。 来源如下:

Set<Address> addressCross = scanList.get(0);
for (int i = 1; i < scanList.size(); i++) {
    addressCross.retainAll(scanList.get(i));
}   
for (Address address : addressCross) {
    addresses.add(address);
}
java set intersection
4个回答
16
投票

您可以使用

retainAll(Collection<?> c)
,查看这里

旁注:该操作称为 交集

要将其转换为

List
,您可以使用方法
addAll(Collection<? extends E> c)
,该方法应该在所有类型的容器之间工作。

例如:

ArrayList<Address> list = new ArrayList<Address>();
list.addAll(yourSet);

13
投票

retainAll

使用

List#retainAll()

引用Javadoc:

仅保留此列表中包含在指定集合中的元素(可选操作)。换句话说,从此列表中删除所有未包含在指定集合中的元素。


8
投票

使用Guava,你可以这样做:

Set<Address> intersection = scanList.get(0);
for (Set<Address> scan : scanList.subList(1, scanList.size())) {
  intersection = Sets.intersection(intersection, scan);
}
List<Address> addresses = Lists.newArrayList(intersection);

这将创建

scanList
中所有集合的交集视图,然后将交集中的地址复制到
List
中。当然,您需要确保您的
scanList
中至少有一个元素。


0
投票

这里还有另一个不错的解决方案:https://stackoverflow.com/a/38266681/349169

Set<Address> intersection = scanList.stream()
    .skip(1) // optional
    .collect(()->new HashSet<>(scanList.get(0)), Set::retainAll, Set::retainAll);
© www.soinside.com 2019 - 2024. All rights reserved.