Java 获取两组之间的差异

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18644579/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 09:47:31  来源:igfitidea点击:

Getting the difference between two sets

javaset

提问by David Tunnell

So if I have two sets:

所以如果我有两套:

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

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

Is there a way to compare them and only have a set of 4 and 5 returned?

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

采纳答案by Prabhaker A

Try this

尝试这个

test2.removeAll(test1);

Set#removeAll

设置#removeAll

Removes from this set all of its elements that are contained in the specified collection (optional operation). If the specified collection is also a set, this operation effectively modifies this set so that its value is the asymmetric set difference of the two sets.

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

回答by arshajii

Yes:

是的:

test2.removeAll(test1)

Although this will mutate test2, so create a copy if you need to preserve it.

虽然这会发生变异test2,但如果您需要保留它,请创建一个副本。

Also, you probably meant <Integer>instead of <int>.

此外,您可能的意思是<Integer>而不是<int>.

回答by Josh M

If you are using Java 8, you could try something like this:

如果您使用的是 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());
}

回答by Mikhail Golubtsov

If you use Guava (former Google Collections) library there is a solution:

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

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

The returned SetViewis a Set, it is a live representation you can either make immutable or copy to another set. test1and test2are left intact.

返回的SetView是 a Set,它是一个实时表示,您可以使其不可变或复制到另一个集合。test1test2完好无损。

回答by akhil_mittal

Java 8

爪哇 8

We can make use of removeIfwhich takes a predicate to write a utility method as:

我们可以使用带有谓词的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;
}

And in case we are still at some prior version then we can use removeAll as:

如果我们仍然处于某个以前的版本,那么我们可以使用 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;
}

回答by pwipo

You can use CollectionUtils.disjunctionto get all differences or CollectionUtils.subtractto get the difference in the first collection.

您可以使用CollectionUtils.disjunction获取所有差异或CollectionUtils.subtract获取第一个集合中的差异。

Here is an example of how to do that:

以下是如何执行此操作的示例:

    var collection1 = List.of(1, 2, 3, 4, 5);
    var collection2 = List.of(2, 3, 5, 6);
    System.out.println(StringUtils.join(collection1, " , "));
    System.out.println(StringUtils.join(collection2, " , "));
    System.out.println(StringUtils.join(CollectionUtils.subtract(collection1, collection2), " , "));
    System.out.println(StringUtils.join(CollectionUtils.retainAll(collection1, collection2), " , "));
    System.out.println(StringUtils.join(CollectionUtils.collate(collection1, collection2), " , "));
    System.out.println(StringUtils.join(CollectionUtils.disjunction(collection1, collection2), " , "));
    System.out.println(StringUtils.join(CollectionUtils.intersection(collection1, collection2), " , "));
    System.out.println(StringUtils.join(CollectionUtils.union(collection1, collection2), " , "));

回答by Bojan Vukasovic

Just to put one example here (system is in existingState, and we want to find elements to remove (elements that are not in newStatebut are present in existingState) and elements to add (elements that are in newStatebut are not present in existingState) :

只是在这里举一个例子(系统在 中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);

  }
}

would output this as a result:

结果会输出这个:

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