我正在尝试测试可能的拓扑,这是一组开放集。要做到这一点,我需要找到集合的联合和交集。这样我就可以创建Generated Topology。我认为我能找到的最好的,至少不需要使用外部库 - 似乎Google有一个具有Multiset功能的Guava
库,就是做following(最后一个答案):< / p>
Set<Set<String>> myCollection = new HashSet<>();
我不知道是否值得尝试学习Multiset的各种方法,当我能以某种方式循环并将集合添加到“myCollection”时。有关使用Multiset
或Bag
等内容的真正好处的建议吗?
更具体地说,我会有一组(超集)子集,例如{{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}}.
的新超集超集不会变得非常大,最多可能只有几十个元素。
答案 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]]
我根据您对问题的定义假定您希望结果中出现空集,因为原始集的第一个和最后一个元素不重叠。