Removing an element while using multiple iterators on a Java HashSet

Viewed 73

I am trying to update a set of Sets based on sharing one or more common elements, when two elements have a (or more) common element, they will be combined to a single element and so on.

For example:

Input: {{1,2}, {3,4,5}, {2,4}, {7,8}}

Output should be: {{1,2,3,4,5}, {7,8}}

Input: {{1, 2}, {5, 8, 9}, {3, 4, 5}, {2, 4, 7}, {7, 8}}

Output should be: {{1, 2, 3, 4, 5, 7, 8, 9}}

Here is my Java implementation,

   static boolean hasCommon(HashSet<Integer> s1, HashSet<Integer> s2)
   {
      for (Integer i : s1)
      {
         if (s2.contains(i))
            return true;
      }
      return false;
   }

   static HashSet<HashSet<Integer>> updateElements(HashSet<HashSet<Integer>> newSetofSets)
   {
      Iterator<HashSet<Integer>> it = newSetofSets.iterator();

      while (it.hasNext())
      {
         HashSet<Integer> s1 = it.next();

         Iterator<HashSet<Integer>> it2 = it;

         while (it2.hasNext())
         {
            HashSet<Integer> s2 = it2.next();

            System.out.println("s1 = " + s1.toString() + ", s2 = " + s2.toString());
            System.out.println(newSetofSets.toString());

            if (hasCommon(s1, s2))
            {
               for (Integer i : s2)
               {
                  s1.add(i);
               }

               it2.remove(); // remove s2 after adding its elements to s1.
               System.out.println(newSetofSets.toString());
            }
         }
         System.out.println(newSetofSets.toString());
      }

      return newSetofSets;
   }

For the input: [[1, 2], [5, 8, 9], [3, 4, 5], [2, 4, 7], [7, 8]]

I'm getting,

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

The first iterator it doesn't move to next element after it2 finished.

Any help to solve this problem will be highly appreciated. Thanks.

1 Answers

You only have one iterator in your code. When you execute the following code:

Iterator<HashSet<Integer>> it2 = it;

You are expecting that an new iterator it2 is created that continues at the position where it left off. This is not the case. What you are doing is creating a new variable that is pointing to the same iterator. This is called 'Pass-by-Reference'.

So now you have 2 variables pointing at the same iterator. When you use it2.next() it is the same as saying it.next(). When the second while loop is completed the iterator is at the end of the list and it.hasNext() will be false because it2.hasNext() is the same as it.hasNext().

Related