获得两组之间的差异

时间:2013-09-05 19:40:10

标签: java set

所以如果我有两套:

Set<int> test1 = new HashSet<Integer>();
test1.add(1);
test1.add(2);
test1.add(3);

Set<int> test2 = new HashSet<Integer>();
test2.add(1);
test2.add(2);
test2.add(3);
test2.add(4);
test2.add(5);

有没有办法比较它们,只返回一组4和5?

8 个答案:

答案 0 :(得分:156)

试试这个

test2.removeAll(test1);

Set#removeAll

  

从此集合中删除指定集合中包含的所有元素(可选操作)。如果指定的集合也是一个集合,则此操作会有效地修改此集合,使其值为两个集合的不对称集合差异。

答案 1 :(得分:97)

如果您使用Guava(以前的Google Collections)库,则有一个解决方案:

SetView<Number> difference = com.google.common.collect.Sets.difference(test2, test1);

返回的SetViewSet,它是一个实时表示,您可以将其设为不可变或复制到另一个集合。 <{1}}和test1保持不变。

答案 2 :(得分:13)

是:

test2.removeAll(test1)

虽然这会改变test2,但如果你需要保留它,请创建一个副本。

此外,您可能需要<Integer>而不是<int>

答案 3 :(得分:4)

Java 8

我们可以利用removeIf,它使用一个谓词将实用程序方法编写为:

// computes the difference without modifying the sets
public static <T> Set<T> differenceJava8(final Set<T> setOne, final Set<T> setTwo) {
     Set<T> result = new HashSet<T>(setOne);
     result.removeIf(setTwo::contains);
     return result;
}

如果我们仍然使用某些以前的版本,则可以将removeAll用作:

public static <T> Set<T> difference(final Set<T> setOne, final Set<T> setTwo) {
     Set<T> result = new HashSet<T>(setOne);
     result.removeAll(setTwo);
     return result;
}

答案 4 :(得分:4)

添加一个我最近使用过的解决方案,这里没有提到。如果您有可用的 Apache Commons Collections,那么您可以使用 SetUtils#difference 方法:

// Returns all the elements of test2 which are not in test1
SetUtils.difference(test2, test1) 

请注意,根据文档,返回的集合是一个不可修改的视图:

<块引用>

返回一个不可修改的视图,其中包含给定 Sets 的差异,用 a\b(或 a-b)表示。 返回的视图包含 a 中不是 b 成员的所有元素。

完整文档:https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/SetUtils.html#difference-java.util.Set-java.util.Set-

答案 5 :(得分:3)

如果您使用的是Java 8,可以尝试这样的方法:

public Set<Number> difference(final Set<Number> set1, final Set<Number> set2){
    final Set<Number> larger = set1.size() > set2.size() ? set1 : set2;
    final Set<Number> smaller = larger.equals(set1) ? set2 : set1;
    return larger.stream().filter(n -> !smaller.contains(n)).collect(Collectors.toSet());
}

答案 6 :(得分:0)

仅在此处举一个示例(系统位于existingState中,我们希望找到要删除的元素(不在newState中但在existingState中的元素)和元素要添加(newState中但existingState中不存在的元素):

public class AddAndRemove {

  static Set<Integer> existingState = Set.of(1,2,3,4,5);
  static Set<Integer> newState = Set.of(0,5,2,11,3,99);

  public static void main(String[] args) {

    Set<Integer> add = new HashSet<>(newState);
    add.removeAll(existingState);

    System.out.println("Elements to add : " + add);

    Set<Integer> remove = new HashSet<>(existingState);
    remove.removeAll(newState);

    System.out.println("Elements to remove : " + remove);

  }
}

将其输出为结果:

Elements to add : [0, 99, 11]
Elements to remove : [1, 4]

答案 7 :(得分:0)

您可以使用.addAll()建立联合,并使用.retainAll()建立交集,并使用.removeIf()从联合中删除交集(或重复元素)。

HashSet union = new HashSet(group1);
union.addAll(group2);
        
System.out.println("Union: " + union);
        
HashSet intersection = new HashSet(group1);
intersection.retainAll(group2);
        
System.out.println("Intersection: " + intersection);
        
HashSet difference = new HashSet(union);
difference.removeIf(n -> (difference.contains(intersection)));
        
System.out.println("Difference: " + difference);