在java中获取两组之间的对称差异的最佳方法是什么?

Sim*_*eon 35 java collections set

我想知道是否有一种快速/干净的方法来获得两组之间的对称差异?

我有:

Set<String> s1 = new HashSet<String>();
s1.add("a");
s1.add("b");
s1.add("c");

Set<String> s2 = new HashSet<String>();
s2.add("b");
Run Code Online (Sandbox Code Playgroud)

我需要这样的东西:

Set<String> diff = Something.diff(s1, s2);
// diff would contain ["a", "c"]
Run Code Online (Sandbox Code Playgroud)

只是为了澄清我需要对称差异.

Phi*_*ler 42

您可以使用Google Guava库中的一些功能(这非常棒,我强烈推荐它!):

Sets.difference(s1, s2);
Sets.symmetricDifference(s1, s2);
Run Code Online (Sandbox Code Playgroud)

差异()symmetricDifference()的 Javadocs

symmetricDifference()完全符合您的要求,但difference()也经常有帮助.

两种方法都返回实时视图,但您可以调用.immutableCopy()生成的集合来获取不变的集合.如果您不想要视图,但需要设置实例,您可以修改,调用.copyInto(s3).有关这些方法,请参阅SetView.

  • @Gus JavaDoc想要说结果是未定义的,如果你使用两个使用不同等价关系的不同集合的方法,例如,计算`HashSet`和`TreeSet`之间的差异可能会有问题.使用带有两个`HashSet`s或两个`TreeSets`等的方法很好. (2认同)

Don*_*oby 32

你想要对称的差异.

public static <T> Set<T> diff(final Set<? extends T> s1, final Set<? extends T> s2) {
    Set<T> symmetricDiff = new HashSet<T>(s1);
    symmetricDiff.addAll(s2);
    Set<T> tmp = new HashSet<T>(s1);
    tmp.retainAll(s2);
    symmetricDiff.removeAll(tmp);
    return symmetricDiff;
}
Run Code Online (Sandbox Code Playgroud)

如果你想要一个库,Apache Commons CollectionUtils

CollectionUtils.disjunction(s1, s2)
Run Code Online (Sandbox Code Playgroud)

返回非泛型Collection.

番石榴套装

Sets.symmetricDifference(s1, s2)
Run Code Online (Sandbox Code Playgroud)

它返回一个不可修改Set的通用Sets.SetView.

番石榴更现代,支持仿制药,但其中任何一种都可行.


Xav*_*ica 5

如果您可以使用Apache-Commons Collections,那么您正在寻找CollectionUtils.disjunction(Collection a, Collection b)。它返回两个集合的对称差。

如果不是,removeAll则将retainAll两个集合的交集()减去两个()的并集addAll

Set<String> intersection = new HashSet<String>(set1);
intersection.retainAll(set2);

Set<String> difference = new HashSet<String>();
difference.addAll(set1);
difference.addAll(set2);
difference.removeAll(intersection);
Run Code Online (Sandbox Code Playgroud)