I’m trying to group some sets in disjoint sets. For example, if I have these 5 sets:
[[1, 3], [2], [1, 5], [6, 8], [1, 7]]
I want to have this result:
[[2], [6, 8], [1, 3, 5, 7]]
Here is the code:
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);
}
}
I am using an iterator over the set, and I want to group 2 sets in one, removing one of them. However, I am having a problem with the Iterator.remove() method.
What this program prints is:
[[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]]
The first time, removing [1, 3] works as expected, but the rest of the times, it does not remove the item. I think it’s because I use addAll(), but why is that? Because I don’t make changes in groups; I only change an element inside it(other) – and the reference is the same, right?
An element of a
HashSetis supposed to have a stablehashCode, but you are mutating them as you iterate over the outer set. That fails in unpredictable, but documented ways.In a
TreeSetthere may also be problems with changing the sort order of the element through mutation.