我需要创建一个集合,它将保存两个集合的交集。如果其中一个集合中存在的值发生更改,那么intersectionSet也会受到影响。
设置测试:
Set<Integer> testSet1 = new HashSet<>();
testSet1.add(1);
testSet1.add(2);
testSet1.add(3);
Set<Integer> testSet2 = new HashSet<>();
testSet2.add(2);
testSet2.add(4);
如果我以这种方式实现intersectionSet,即使testSet1或testSet2发生更改也不会受到影响。
Set<Integer> intersectionSet = new HashSet<>(testSet1);
intersectionSet.removeIf(element -> !testSet2.contains(element));
如果我以这种方式实现它,在创建intersectionSet时,testSet1或testSet2将被.removeIf()修改,但这里只删除对intersectionSet中的值的引用。
Set<Integer> intersectionSet;
intersectionSet = testSet1;
intersectionSet.removeIf(element -> !testSet2.contains(element));
通常,intersectionSet应该保持对testSet1和testSet2中适合该条件的值的引用。
问题是,如何实现intersectionSet,它依赖于testSet1和testSet2(及其内容),并且不会改变它们。
我需要这样的事情:
System.out.println(testSet1.contains(1)); // print true
IntersectionSet intersectionSet = new IntersectionSet(testSet1, testSet2);
System.out.println(testSet1.contains(1)); // print true
System.out.println(testSet2.contains(4)); // print true
System.out.println(intersectionSet.contains(2)); // print true
testSet1.remove(2);
System.out.println(intersectionSet.contains(2)); // print false
我的代码如下:
interface OMOSetView {
boolean contains(int element); // test if element is in set
int[] toArray(); //return copy of elemets from set in array
OMOSetView copy(); //return copy of set
int size(); //return size of set
HashSet<Integer> getSet(); //retunrn set
}
// class which represents common set, defines methods add/remove
class OMOSet implements OMOSetView {
private HashSet<Integer> omoSet = new HashSet<>();
public void add(int element) {
if (!omoSet.contains(element)) {
omoSet.add(element);
}
}
public void remove(int element) {
if (omoSet.contains(element)) {
omoSet.remove(element);
}
}
public boolean contains(int element) {
return omoSet.contains(element);
}
public int[] toArray() {
int[] array = new int[omoSet.size()];
int i = 0;
for (Integer element : omoSet) {
array[i] = element;
i++;
}
return array;
}
public OMOSet copy() {
OMOSet copySet = new OMOSet();
for (Integer element : omoSet) {
copySet.add(element);
}
return copySet;
}
public int size() {
return omoSet.size();
}
public HashSet<Integer> getSet() {
return this.omoSet;
}
}
// class represents intersectionSet of two sets A and B
class OMOSetIntersection implements OMOSetView {
private HashSet<Integer> intersectionSet;
OMOSetIntersection(OMOSetView setA, OMOSetView setB) {
intersectionSet = setA.getSet(); // it's not working
intersectionSet.removeIf(element -> !setB.contains(element)); // it's not working
}
public boolean contains(int element) {
return intersectionSet.contains(element);
}
public int[] toArray() {
int[] array = new int[intersectionSet.size()];
int i = 0;
for (Integer element : intersectionSet) {
array[i] = element;
i++;
}
return array;
}
public OMOSet copy() {
OMOSet copySet = new OMOSet();
for (Integer element : intersectionSet) {
copySet.add(element);
}
return copySet;
}
public int size() {
return intersectionSet.size();
}
public HashSet<Integer> getSet() {
return intersectionSet;
}
}
答案 0 :(得分:0)
您应该使用实现延迟计算的包装器:这意味着它们不保存实际的交集元素,而是保留对原始集的引用并根据请求提供交集。
Google Guava提供了一系列延迟计算的集合实用程序。在您的情况下,com.google.common.collect.Sets#intersection(Set<E> set1, Set<?> set2)
是一种方法:
Set<Integer> testSet1 = new HashSet<>();
testSet1.add(1);
testSet1.add(2);
testSet1.add(3);
Set<Integer> testSet2 = new HashSet<>();
testSet2.add(2);
testSet2.add(4);
Set<Integer> intersectionSet = Sets.intersection(testSet1, testSet2);