我正在尝试将一些集合分成不相交的集合。例如,如果我有这5套:
[[1,3],[2],[1,5],[6,8],[1,7]]
我希望得到这样的结果:
[[2],[6,8],[1,3,5,7]]
以下是代码:
import java.util.*;
public class SetTest {
public static void main(String[] args) {
// ---- Initialisation
Set<Set<Integer>> groups = new LinkedHashSet<Set<Integer>>();
for (int[] set : new int[][] { {1, 3 }, {2 }, {1, 5 }, {6, 8 }, {1, 7} }) {
Set<Integer> group = new TreeSet<Integer>();
for (int i : set) {
group.add(i);
}
groups.add(group);
}
System.out.println(groups);
// ---- Grouping values in disjoint sets
for (Iterator<Set<Integer>> iterator = groups.iterator(); iterator.hasNext();) {
Set<Integer> group = iterator.next();
System.out.println(String.format(" + Checking %20s in \t %s", group, groups));
for (Set<Integer> other : groups) {
if (!group.equals(other) && !Collections.disjoint(group, other)) {
other.addAll(group);
iterator.remove();
System.out.println(String.format(" - Removed %20s -> \t %s", group, groups));
break;
}
}
}
System.out.println(groups);
}
}
我在集合上使用迭代器,我想将2个集合在一起,删除其中一个。但是,我遇到了Iterator.remove()
方法的问题
这个程序打印的是:
[[1, 3], [2], [1, 5], [6, 8], [1, 7]]
+ Checking [1, 3] in [[1, 3], [2], [1, 5], [6, 8], [1, 7]]
- Removed [1, 3] -> [[2], [1, 3, 5], [6, 8], [1, 7]]
+ Checking [2] in [[2], [1, 3, 5], [6, 8], [1, 7]]
+ Checking [1, 3, 5] in [[2], [1, 3, 5], [6, 8], [1, 7]]
- Removed [1, 3, 5] -> [[2], [1, 3, 5], [6, 8], [1, 3, 5, 7]]
+ Checking [6, 8] in [[2], [1, 3, 5], [6, 8], [1, 3, 5, 7]]
+ Checking [1, 3, 5, 7] in [[2], [1, 3, 5], [6, 8], [1, 3, 5, 7]]
- Removed [1, 3, 5, 7] -> [[2], [1, 3, 5, 7], [6, 8], [1, 3, 5, 7]]
[[2], [1, 3, 5, 7], [6, 8], [1, 3, 5, 7]]
第一次删除[1, 3]
按预期工作,但其余时间,它不会删除该项目。我认为这是因为我使用addAll()
,但为什么呢?因为我没有在groups
中进行更改;我只更改其中的元素(other
) - 并且引用是相同的,对吧?
答案 0 :(得分:2)
HashSet
的元素应该具有稳定的hashCode
,但是当您迭代外部集合时,您正在改变它们。这在不可预测但有记录的方式上失败了。
在TreeSet
中,通过变异更改元素的排序顺序也可能存在问题。