获得两组之间的差异

Dav*_*ell 138 java set

所以如果我有两套:

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);
Run Code Online (Sandbox Code Playgroud)

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

Pra*_*ker 173

试试这个

test2.removeAll(test1);
Run Code Online (Sandbox Code Playgroud)

集#的removeAll

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

  • 当Java没有定义`union`,`intersection`或`difference`时,Java怎么能把这个数据结构称为`Set`! (107认同)
  • 这将工作,但我认为这将是一个很好的功能,使用像union这样的集合操作.上面的解决方案将修改集合,在很多情况下我们并不真正想要它. (37认同)
  • 这个解决方案并不完全正确.因为test1和test2的顺序有所不同. (9认同)
  • @BojanPetkovic 这给出了 `test1` 中不存在的 `test2` 元素,这正是 OP 所要求的。 (3认同)
  • @datv结果将有所不同。test1.removeAll(test2)是一个空集。test2.removeAll(test1)是{4,5}。 (2认同)
  • 与双大括号结合使用会非常有用:`new HashSet(set1) {{removeAll(set2); }};` (2认同)

Mik*_*sov 107

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

SetView<Number> difference = com.google.common.collect.Sets.difference(test2, test1);
Run Code Online (Sandbox Code Playgroud)

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

  • 请注意[订单](https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/Sets.html#difference(java.util.Set,%20java. util.Set))test2和test1很重要.还有[symmetricDifference()](https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/Sets.html#symmetricDifference(java.util.Set,% 20java.util.Set))订单无关紧要. (5认同)
  • `symmetryDifference()` 将带来除交集之外的所有内容,这不是原始问题所要求的。 (2认同)

ars*_*jii 15

是:

test2.removeAll(test1)
Run Code Online (Sandbox Code Playgroud)

虽然这会发生变异test2,但如果需要保留副本,请创建副本.

此外,你可能意味着<Integer>而不是<int>.


pwi*_*ipo 6

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

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>4.4</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

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

import org.apache.commons.collections4.CollectionUtils;
import java.util.List;

var collection1 = List.of(-1, 0, 1, 2, 3, 4, 5);
var collection2 = List.of(       1, 2, 3, 4, 5, 6, 7, 8, 9);

// [-1, 0, 1, 2, 3, 4, 5]
System.out.println(collection1);
// [1, 2, 3, 4, 5, 6, 7, 8, 9]
System.out.println(collection2);

// [-1, 0]
System.out.println(CollectionUtils.subtract(collection1, collection2));
// [6, 7, 8, 9]
System.out.println(CollectionUtils.subtract(collection2, collection1));

// [1, 2, 3, 4, 5]
System.out.println(CollectionUtils.retainAll(collection1, collection2));
// [1, 2, 3, 4, 5]
System.out.println(CollectionUtils.retainAll(collection2, collection1));

// [-1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9]
System.out.println(CollectionUtils.collate(collection1, collection2));
// [-1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9]
System.out.println(CollectionUtils.collate(collection2, collection1));

// [-1, 0, 6, 7, 8, 9]
System.out.println(CollectionUtils.disjunction(collection1, collection2));
// [-1, 0, 6, 7, 8, 9]
System.out.println(CollectionUtils.disjunction(collection2, collection1));

// [1, 2, 3, 4, 5]
System.out.println(CollectionUtils.intersection(collection1, collection2));
// [1, 2, 3, 4, 5]
System.out.println(CollectionUtils.intersection(collection2, collection1));

// [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
System.out.println(CollectionUtils.union(collection1, collection2));
// [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
System.out.println(CollectionUtils.union(collection2, collection1));
Run Code Online (Sandbox Code Playgroud)

  • `CollectionUtils` 来自哪个项目?1 是否必须假设它来自 Apache Commons Collection? (15认同)

i_a*_*ero 5

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;
}
Run Code Online (Sandbox Code Playgroud)

如果我们仍旧使用某些早期版本,则可以将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;
}
Run Code Online (Sandbox Code Playgroud)


Boj*_*vic 5

举一个例子(系统位于 中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);

  }
}
Run Code Online (Sandbox Code Playgroud)

将输出以下结果:

Elements to add : [0, 99, 11]
Elements to remove : [1, 4]
Run Code Online (Sandbox Code Playgroud)


Mat*_*son 5

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

// Returns all the elements of test2 which are not in test1
SetUtils.difference(test2, test1) 
Run Code Online (Sandbox Code Playgroud)

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

返回一个不可修改的视图,其中包含给定 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-