Удаление элемента при использовании нескольких итераторов в Java HashSet - PullRequest
2 голосов
/ 25 февраля 2020

Я пытаюсь обновить набор Наборов на основе совместного использования одного или нескольких общих элементов, когда два элемента имеют (или более) общий элемент, они будут объединены в один элемент и так далее.

Например:

Ввод: {{1,2}, {3,4,5}, {2,4}, {7,8}}

Выход должен быть: {{1,2,3,4,5}, {7,8}}

Ввод: {{1, 2}, {5, 8, 9}, {3, 4, 5}, {2, 4, 7}, {7, 8}}

Вывод должен быть: {{1, 2, 3, 4, 5, 7, 8, 9}}

Вот моя Java реализация,

   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;
   }

Для ввода: [[1, 2], [5, 8, 9], [3, 4, 5], [2, 4, 7], [7, 8]]

Я получаю,

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

Первый итератор it не перемещается к следующему элементу после завершения it2.

Любая помощь для решения этой проблемы будет высоко оценена. Спасибо.

1 Ответ

1 голос
/ 25 февраля 2020

В вашем коде только один итератор. Когда вы выполняете следующий код:

Iterator<HashSet<Integer>> it2 = it;

Вы ожидаете, что будет создан новый итератор it2, продолжающийся в позиции, где остановился it. Это не вариант. Что вы делаете, это создаете новую переменную, которая указывает на тот же итератор. Это называется «передача по ссылке».

Итак, теперь у вас есть 2 переменные, указывающие на одного итератора. Когда вы используете it2.next(), это то же самое, что сказать it.next(). Когда второй, в то время как l oop завершен, итератор находится в конце списка, и it.hasNext() будет ложным, потому что it2.hasNext() совпадает с it.hasNext().

...