[英]What is the best way get the symmetric difference between two sets in java?
我想知道是否有一种快速/干净的方法来获得两组之间的对称差异?
我有:
Set<String> s1 = new HashSet<String>();
s1.add("a");
s1.add("b");
s1.add("c");
Set<String> s2 = new HashSet<String>();
s2.add("b");
我需要类似的东西:
Set<String> diff = Something.diff(s1, s2);
// diff would contain ["a", "c"]
只是为了澄清我需要对称差异。
你想要对称差异。
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;
}
如果你想要一个库, Apache Commons CollectionUtils有
CollectionUtils.disjunction(s1, s2)
它返回一个非泛型Collection
。
和番石榴集有
Sets.symmetricDifference(s1, s2)
它返回一个不可修改的Set
作为通用Sets.SetView
。
Guava 更现代一些,支持泛型,但其中任何一个都可以。
如果您可以使用Apache-Commons Collections ,那么您正在寻找CollectionUtils.disjunction(Collection a, Collection b)
。 它返回两个集合的对称差异。
如果不是,则将两个集合的交集 ( retainAll
) 减去 ( removeAll
) 到两个集合的并集 ( 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);
循环遍历一组并进行比较。
循环遍历其中一组只需O(n)
。 考虑这个代码:
for (String key: oldSet) {
if (newSet.contains(key))
newSet.remove(key);
else
newSet.add(key);
}
并且newSet
现在将只包含来自两个集合的唯一条目。 它很快,因为您只需要遍历其中一个集合中的元素,并且除非您明确需要副本,否则不必创建集合。
public class Practice {
public static void main(String[] args) {
Set<Integer> set1 = new HashSet<Integer>();
Set<Integer> set2 = new HashSet<Integer>();
set1.add(1);
set1.add(4);
set1.add(7);
set1.add(9);
set2.add(2);
set2.add(4);
set2.add(5);
set2.add(6);
set2.add(7);
symmetricSetDifference(set1, set2);
}
public static void symmetricSetDifference(Set<Integer>set1, Set<Integer>set2){
//creating a new set
Set<Integer> newSet = new HashSet<Integer>(set1);
newSet.removeAll(set2);
set2.removeAll(set1);
newSet.addAll(set2);
System.out.println(newSet);
}
}
我们可以在某些类SetUtils (say)
编写两个实用程序方法(对于 java 8 和之前的),如下所示:
public static <T> Set<T> symmetricDifferenceJava8(final Set<T> setOne, final Set<T> setTwo) {
Set<T> result = new HashSet<>(setOne);
setTwo.stream().filter(not(resultSet::add)).forEach(resultSet::remove);
return result;
}
public static <T> Set<T> symmetricDifference(final Set<T> setOne, final Set<T> setTwo) {
Set<T> result = new HashSet<T>(setOne);
for (T element : setTwo) {
if (!result.add(element)) {
result.remove(element);
}
}
return result;
}
public static <T> Predicate<T> not(Predicate<T> t) {
return t.negate();
}
如果元素已经存在,则方法add
返回 false 并且方法 negate 用于否定谓词。
我们在 Java 11 中有一个Predicate#not谓词方法,可以将它用作:
public static <T> Set<T> symmetricDifferenceJava11(final Set<T> setOne, final Set<T> setTwo) {
Set<T> result = new HashSet<>(setOne);
setTwo.stream().filter(Predicate.not(resultSet::add)).forEach(resultSet::remove);
return result;
}
public class Practice {
public static void main(String[] args) {
Set<Integer> set1 = new HashSet<Integer>();
Set<Integer> set2 = new HashSet<Integer>();
set1.add(1);
set1.add(4);
set1.add(7);
set1.add(9);
set2.add(2);
set2.add(4);
set2.add(5);
set2.add(6);
set2.add(7);
symmetricSetDifference(set1, set2);
}
public static void symmetricSetDifference(Set<Integer>set1, Set<Integer>set2){
//creating a new set
Set<Integer> newSet = new HashSet<Integer>(set1);
newSet.removeAll(set2);
set2.removeAll(set1);
newSet.addAll(set2);
System.out.println(newSet);
}
如果a
和b
是集合
a - b
是a
中不在b
。
>>> a = {1,2,3}
>>> b = {1,4,5}
>>>
>>> a - b
{2, 3}
>>> b - a
{4, 5}
a.symmetric_difference(b)
是恰好在一个集合中的所有元素,例如a - b
和b - a
。
>>> a.symmetric_difference(b)
{2, 3, 4, 5}
>>> (a - b).union(b - a)
{2, 3, 4, 5}
来自 io.datakernel.common.collection
public static <T> Set<T> difference(Set<? extends T> a, Set<? extends T> b) {
return a.stream().filter(t -> !b.contains(t)).collect(toSet());
}
我想知道是否有一种快速/干净的方法来获得两组之间的对称差异?
我有:
Set<String> s1 = new HashSet<String>();
s1.add("a");
s1.add("b");
s1.add("c");
Set<String> s2 = new HashSet<String>();
s2.add("b");
我需要类似的东西:
Set<String> diff = Something.diff(s1, s2);
// diff would contain ["a", "c"]
只是为了澄清一下,我需要对称的区别。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.