Список Java и рекурсия приводят к исключению одновременной модификации - PullRequest
3 голосов
/ 05 января 2012

Следующая функция рекурсивно проходит по списку, всегда делит его пополам и что-то делает с подсписками. Рекурсия прерывается, когда размер списка равен 2. Я знаю, что происходит параллельное исключение модификации, если я изменяю список, когда я повторяю его. Но я не использую итерации, и это все еще происходит:

    private static List<ParticipantSlot> divide(List<ParticipantSlot> list) {
        int n = list.size();

        //do something 

        if (n>2){
            List<ParticipantSlot> l = divide(list.subList(0, n/2-1));
            List<ParticipantSlot> r= divide(list.subList(n/2, n));

            l.addAll(r);
            return l;
        }else{
            return list;
        }
    }

Ответы [ 3 ]

7 голосов
/ 05 января 2012

Вы используете addAll(), который будет перебирать коллекцию, указанную в аргументе.Теперь subList возвращает только представление в исходный список, поэтому вы пытаетесь добавить значения в представление исходного списка и одновременно перебирать другую часть исходного списка.Bang.

Если вы каждый раз создавали копию подсписка, это должно сработать - хотя это будет довольно неэффективно.

3 голосов
/ 05 января 2012

Вы получаете одновременное исключение модификации, поскольку подсписок поддерживается исходным списком:

Возвращенный список поддерживается этим списком, поэтому неструктурные изменения в возвращенном списке отражаются в этом списке, и наоборот.Возвращенный список поддерживает все необязательные операции со списком, поддерживаемые этим списком.

Если вы хотите избежать исключения, сделайте копию первого подсписка перед его изменением.

1 голос
/ 05 января 2012

Если вы используете ArrayList, вы можете изменить его на CopyOnWriteArrayList или ConcurrentLinkedQueue .

Если вы используете многопоточную среду,вы захотите поместить synchronized вокруг вашего массива.

Надеюсь, это поможет.

...