如何计算两个以上 HashSet 之间的交集?
How do I calculate intersection between more than two HashSets?
考虑到下面的代码以及 4 个 HashSet
填充在其他地方的事实。
我的目标是包含所有 4 个 HashSet 中共有的所有元素。
我的问题是,首先,我做得对吗?其次,如果我做对了,还有更好的方法吗?如果没有,那我有什么办法解决这个问题?
static Set<String> one=new HashSet<>();
static Set<String> two=new HashSet<>();
static Set<String> three=new HashSet<>();
static Set<String> four=new HashSet<>();
private static void createIntersectionQrels() {
ArrayList<String> temp = new ArrayList<>();
Set<String> interQrels = new HashSet<>();
temp.addAll(one);
one.retainAll(two);
interQrels.addAll(one);
one.addAll(temp);
one.retainAll(three);
interQrels.addAll(one);
one.addAll(temp);
one.retainAll(four);
interQrels.addAll(one);
one.addAll(temp);
interQrels.retainAll(two);
interQrels.retainAll(three);
interQrels.retainAll(four);
}
我认为处理此问题的最佳方法是 Groovy。我知道你没有要求 groovy,但任何时候我都可以将所有代码转换成一行,这很难抗拒。
println one.intersect(two).intersect(three).intersect(four)
我认为您可以简单地在第一组上调用 retainAll()
,使用第二、第三和第四组作为参数:
private static Set<String> getIntersectionSet() {
// create a deep copy of one (in case you don't wish to modify it)
Set<String> interQrels = new HashSet<>(one);
interQrels.retainAll(two); // intersection with two (and one)
interQrels.retainAll(three); // intersection with three (and two, one)
interQrels.retainAll(four); // intersection four (and three, two, one)
return interQrels;
}
我对 Java 8 有点陌生,但这看起来很易读:
Set<String> intersection = one.stream()
.filter(two::contains)
.filter(three::contains)
.filter(four::contains)
.collect(Collectors.toSet());
这里有一个快速的 Junit 测试可以试用:
@Test
public void testIntersectionBetweenSets() {
Collection<String> one = new HashSet<>(4);
one.add("Larry");
one.add("Mark");
one.add("Henry");
one.add("Andrew");
Set<String> two = new HashSet<>(2);
two.add("Mark");
two.add("Andrew");
Set<String> three = new HashSet<>(3);
three.add("Mark");
three.add("Mary");
three.add("Andrew");
Set<String> four = new HashSet<>(3);
four.add("Mark");
four.add("John");
four.add("Andrew");
Set<String> intersection = one.stream()
.filter(two::contains)
.filter(three::contains)
.filter(four::contains)
.collect(Collectors.toSet());
Collection<String> expected = new HashSet<>(2);
expected.add("Andrew");
expected.add("Mark");
Assert.assertEquals(expected, intersection);
}
考虑到下面的代码以及 4 个 HashSet
填充在其他地方的事实。
我的目标是包含所有 4 个 HashSet 中共有的所有元素。
我的问题是,首先,我做得对吗?其次,如果我做对了,还有更好的方法吗?如果没有,那我有什么办法解决这个问题?
static Set<String> one=new HashSet<>();
static Set<String> two=new HashSet<>();
static Set<String> three=new HashSet<>();
static Set<String> four=new HashSet<>();
private static void createIntersectionQrels() {
ArrayList<String> temp = new ArrayList<>();
Set<String> interQrels = new HashSet<>();
temp.addAll(one);
one.retainAll(two);
interQrels.addAll(one);
one.addAll(temp);
one.retainAll(three);
interQrels.addAll(one);
one.addAll(temp);
one.retainAll(four);
interQrels.addAll(one);
one.addAll(temp);
interQrels.retainAll(two);
interQrels.retainAll(three);
interQrels.retainAll(four);
}
我认为处理此问题的最佳方法是 Groovy。我知道你没有要求 groovy,但任何时候我都可以将所有代码转换成一行,这很难抗拒。
println one.intersect(two).intersect(three).intersect(four)
我认为您可以简单地在第一组上调用 retainAll()
,使用第二、第三和第四组作为参数:
private static Set<String> getIntersectionSet() {
// create a deep copy of one (in case you don't wish to modify it)
Set<String> interQrels = new HashSet<>(one);
interQrels.retainAll(two); // intersection with two (and one)
interQrels.retainAll(three); // intersection with three (and two, one)
interQrels.retainAll(four); // intersection four (and three, two, one)
return interQrels;
}
我对 Java 8 有点陌生,但这看起来很易读:
Set<String> intersection = one.stream()
.filter(two::contains)
.filter(three::contains)
.filter(four::contains)
.collect(Collectors.toSet());
这里有一个快速的 Junit 测试可以试用:
@Test
public void testIntersectionBetweenSets() {
Collection<String> one = new HashSet<>(4);
one.add("Larry");
one.add("Mark");
one.add("Henry");
one.add("Andrew");
Set<String> two = new HashSet<>(2);
two.add("Mark");
two.add("Andrew");
Set<String> three = new HashSet<>(3);
three.add("Mark");
three.add("Mary");
three.add("Andrew");
Set<String> four = new HashSet<>(3);
four.add("Mark");
four.add("John");
four.add("Andrew");
Set<String> intersection = one.stream()
.filter(two::contains)
.filter(three::contains)
.filter(four::contains)
.collect(Collectors.toSet());
Collection<String> expected = new HashSet<>(2);
expected.add("Andrew");
expected.add("Mark");
Assert.assertEquals(expected, intersection);
}