0

I have a set like this :

Set<Set<Node>> NestedSet = new HashSet<Set<Node>>();

[[Node[0], Node[1], Node[2]], [Node[0], Node[2], Node[6]], [Node[3], Node[4], Node[5]]]

I want to compare and merge sets that are inside the nested set. [0,1,2] and [0,2,6] has element in common. so should merge them to form 0,1,2,6.

The output should be like this:

[[Node[0], Node[1], Node[2], Node[6]], [Node[3], Node[4], Node[5]]]

Is there any efficient way?

priya
  • 375
  • 5
  • 22
  • You can use https://github.com/google/guava to have intersection between two nested set if intersection > 0 then you merge the two sets. Of course this is not the most efficient way because you have to compare in the worst case O(n^2) elements. – Tommaso Pasini Jan 23 '16 at 13:13

1 Answers1

1

You can use Collections.disjoint(Collection c1, Collection c2) to check two specified collections have no elements in common.

Btw make sure your Node class implemented hashCode and equals

Set<Set<Node>> result = new HashSet<Set<Node>>();
for (Set<Node> s1 : NestedSet) {
    Optional<Set<Node>> findFirst = result.stream().filter(p -> !Collections.disjoint(s1, p)).findFirst();
    if (findFirst.isPresent()){
        findFirst.get().addAll(s1); 
    }
    else {
        result.add(s1);
    }
}
Viet
  • 3,349
  • 1
  • 16
  • 35
  • Thank you so much for your help. It worked! But if I want to add it to S1 set, only when it has two common elements, then how it should be ? something like this : if (findFirst.isPresent() and count =2) then add?? Is it possible ? – priya Jan 23 '16 at 19:20
  • Yes you can do it with using retainAll function : Optional> findFirst = result.stream().filter(p -> { HashSet temp = new HashSet<>(s1); temp.retainAll(p); return temp.size() == 2; }).findFirst(); – Viet Jan 24 '16 at 04:03
  • Thanks a lot again ! but something went wrong with this. This is the follow up . [link](http://stackoverflow.com/questions/34974460/merge-sets-when-two-elements-in-common) . Could you refer this link. – priya Jan 24 '16 at 10:08