Не разрешено манипулировать TreeSet в цикле for

У меня есть TreeSet, содержащий целые числа. Я перебираю этот набор и «потребляю» целые числа одно за другим. В каждом цикле мне нужно увеличивать оставшиеся неизрасходованные целые числа на 1.

Например, я начинаю с набора из четырех значений: 2, 3, 5, 8. После первого цикла, где я потребляю 2, результатом должен быть набор с этим содержимым 4, 6 , 9. После второго цикла, где потребляется 4, должно быть 7, 10 и так далее.

  • Мне не нужно, чтобы последнее значение увеличивалось на шаг после того, как оно было использовано (но это нормально, если это так).
  • Это нормально, если потребляемые значения остаются в наборе, и не имеет значения, находятся ли они в исходном или увеличенном значении. Другими словами, после второго цикла было бы нормально, если бы набор содержал 2, 3, 7, 10 или 2, 4, 7, 10, или просто 7, 10. (Набор будет удален после этого цикла)

это мой код

    for (Integer i : positionSet) {
        TreeSet <Integer> tmpSet = new TreeSet<>(); 
        //use i for something
        //positionSet.remove(i); //I tried with this both on and off, but it made no difference
        for (Integer j : positionSet) {
            tmpSet.add(j + 1);
        }
        positionSet.clear();
        positionSet.addAll(tmpSet);
    }

Он вылетает во втором раунде с java.util.ConcurrentModificationException, что, как я полагаю, вызвано тем, что я изменил набор, который используется в заголовке цикла.

Как изменить содержимое набора во время цикла? Я пытался копировать набор туда и обратно несколькими разными способами, но код постоянно дает сбой с одним и тем же сообщением об ошибке. Я не должен изменять набор во время цикла, однако вся цель этого цикла заключается в изменении набора.//

Какой результат вы ожидаете? Вы возвращаете значение из этого метода? или ожидаете, что результаты будут в наборе?

Arun Gowda 11.12.2020 14:03

Вы должны использовать настоящие итераторы, а не циклы for-each.

NomadMaker 11.12.2020 14:04

Моя конечная цель — вставить в строку случайное количество точек в соответствии с определенными правилами: (1) Первый и последний символы не должны быть точкой. (2) Две точки подряд не допускаются. Другими словами, если у меня есть строка из шести символов ABCDEF, максимально допустимое количество точек равно 5 (но от 0 до 4 допустимо). Следующие результаты действительны A.B.C.D.E.F, AB.CDEF, AB.C.D.EF, а эти два недействительны .AB.C.DEF, A.BCD.EF..

d-b 11.12.2020 14:04

Отвечает ли это на ваш вопрос? Удалять элементы из коллекции во время итерации

Glains 11.12.2020 14:07

Мой общий алгоритм выглядит следующим образом: (1) длина строки -1 используется для получения случайного значения количества точек, которые следует использовать. (2) цикл до тех пор, пока TreeSet не будет иметь количество элементов, определяемое (1). Эти элементы определяют позицию, в которую вставляется точка, и являются случайными. Опять же, длина строки используется для ограничения значения случайного числа. После этого я выполняю эту петлю. Причина этого +1 состоит в том, чтобы предотвратить попадание точек рядом друг с другом.

d-b 11.12.2020 14:10

@Glains TreeSet есть Collection.

Mark Rotteveel 12.12.2020 14:16
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
6
153
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы не можете изменять структуру данных во время итерации, за исключением разрешенных положений. Для итератора это только Iterator.remove(), но для каждого такого положения нет, и вы не можете влиять на другие элементы.

Лучшее, что вы можете сделать, это создать цикл while, не зависящий от структуры данных:

while (!positionSet.isEmpty()) {
    Integer i = <take one element out of positionSet somehow>;
    //positionSet.remove(i); //remove if the previous line didn't already remove it

    //use i for something
    TreeSet <Integer> tmpSet = new TreeSet<>();
    for (Integer j : positionSet) {
        tmpSet.add(j + 1);
    }
    positionSet.clear();
    positionSet.addAll(tmpSet);
}

Другие вопросы по теме