Java中集合的联合和交集(生成拓扑)

时间:2017-04-26 23:53:14

标签: java collections set

我正在尝试测试可能的拓扑,这是一组开放集。要做到这一点,我需要找到集合的联合和交集。这样我就可以创建Generated Topology。我认为我能找到的最好的,至少不需要使用外部库 - 似乎Google有一个具有Multiset功能的Guava库,就是做following(最后一个答案):< / p>

Set<Set<String>> myCollection = new HashSet<>();

我不知道是否值得尝试学习Multiset的各种方法,当我能以某种方式循环并将集合添加到“myCollection”时。有关使用MultisetBag等内容的真正好处的建议吗?

更具体地说,我会有一组(超集)子集,例如{{A,B,D}, {B,C}},我们可以看到{A,B,D} U {B,C} = {A,B,C,D}${A,B,D} ∩ {B,C} = {B}$因此{{A,B,D}, {B,C}, {B}, {A,B,C,D}}.的新超集超集不会变得非常大,最多可能只有几十个元素。

2 个答案:

答案 0 :(得分:1)

Multiset需要包含多个相同元素的Set时,Set非常有用(因为Set只能包含每个元素中的一个)。

如果您正在寻找多个Sets.java的联合或交集,那么我执行建议使用Google的Guava库,因为它具有以下内容在static <E> Sets.SetView<E> union(Set<? extends E> set1, Set<? extends E> set2) static <E> Sets.SetView<E> intersection(Set<E> set1, Set<?> set2) 中对您有用的方法:

Set<Integer> first = new HashSet<>(Arrays.asList(1, 3, 5, 7));
Set<Integer> second = new HashSet<>(Arrays.asList(2, 4, 6, 8));

// Creates a new Set as a copy of 'first' and then adds every element from 'second' into the new Set, creating a union.
Set<Integer> union = new HashSet<>(first);

union.addAll(second);

System.out.println(union);

>> {1, 2, 3, 4, 5, 6, 7, 8}

// Creates a new Set as a copy of 'first' and then removes every element from the new Set that is not contained within 'second', creating an intersection.
Set<Integer> intersection = new HashSet<>(first);

intersection.retainAll(second);

System.out.println(intersection);

>> {}

如果您不想使用Guava,那么有些方法可以在Java中找到两个集合的并集和交集:

  public void run() {
    boolean debug = true;
    if (debug) {
        System.out.println("run debugging output enabled");
        System.out.println("time: " + time);
    }
    previousTime = time;
    time = System.currentTimeMillis();
    while (running) {
        previousTime = time;
        time = System.currentTimeMillis();
        for (Number n : numbers.values()) {
            n.update(time - previousTime);
        }
        if (debug)
            System.out.println("new time: " + time + "\n time difference: " + (time - previousTime));
        try{
            Thread.sleep(300);
        }
        catch(Exception e){

        }
        gui.getGameControl().repaint();

    }
}

答案 1 :(得分:0)

如果我正确理解您的问题,您需要一个接收一组集合的方法,并添加一个或多个成员的联合或一个或多个成员的交集的任何集合。

如果这是正确的,那么它当然可以用标准Java完成 - 不需要Guava或其他库。

编写寻找联合或交集的方法非常简单:

Set<T> union(Set<Set<T>> sets) {
    return sets.stream().reduce(new HashSet<>(), 
        (s1, s2) -> {
            s1.addAll(s2);
            return s1;
        });
}

交叉点稍微困难:您需要复制集合以避免更改它们:

Set<T> intersection(Set<Set<T>> sets) {
    return sets.stream().map(HashSet::new).reduce(
        (s1, s2) -> {
            s1.retainAll(s2);
            return s1;
        });
}

更复杂的一点:对所有成员组合执行这些操作。

void topology(Set<Set<T>> sets) {
    process(new HashSet<>(sets), sets);
}

private void process(Set<Set<T>> input, Set<Set<T>> output) {
    if (!input.isEmpty()) {
        output.add(union(input));
        output.add(intersection(input));
        input.stream().forEach(el1 -> 
            process(input.stream().filter(el2 -> !el1.equals(el2))
                .collect(toSet()), output));
    }
}

如果您需要进一步解释这些方法,请在评论中告诉我们。

我使用集合{{1,3,5},{2,3,7},{4,7,9}}尝试了这一点并收到了结果:

[[], [1, 2, 3, 5, 7], [3], [4, 7, 9], [7], [1, 3, 5], [2, 3, 4, 7, 9], [2, 3, 7], [1, 3, 4, 5, 7, 9], [1, 2, 3, 4, 5, 7, 9]]

我根据您对问题的定义假定您希望结果中出现空集,因为原始集的第一个和最后一个元素不重叠。

相关问题