在Java中创建抽象数据类型

时间:2017-10-26 18:44:23

标签: java collections reference hashset

我需要创建一个集合,它将保存两个集合的交集。如果其中一个集合中存在的值发生更改,那么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;
    }
}

1 个答案:

答案 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);