Выдаленне элемента з калекцыі выклікаў java.util.ConcurrentModificationException

Я спрабаваў стварыць рэйтынг з двух адсартаваных спісаў.

 List> rankedList = Collections.synchronizedList(WebCBIR.run(queryData, clusters, idf));
 List> rankedList2 = Collections.synchronizedList(WebCBIR.run(queryData, clusters));
 LinkedList> result = new LinkedList<>();
 Iterator> it = rankedList.iterator();
 Iterator> it2 = rankedList2.iterator();

 while (it.hasNext() && it2.hasNext())  {

        Ordered o1 = it.next();
        Ordered o2 = it2.next();
        Ordered o = null;
        if(o1.value() > o2.value()){
            o = o1;
            rankedList.remove(o);
            rankedList2.remove(o);
        }
        else{
            o = o2;
            rankedList.remove(o);
            rankedList2.remove(o);

        }
        result.add(o);
}

Гэты код выклікае java.util.ConcurrentModificationException. Як з гэтым змагацца?

2
Гэта выключэнне павінна было назваць ModificationWhileIteratingException . ці ёсць зэканоміць шмат блытаніны, паколькі резьб паралелізм не мае нічога агульнага з памылкай. Гэта далёка не першы падобны пытанне аб SO!
дададзена аўтар yshavit, крыніца
Гэта выключэнне павінна было назваць ModificationWhileIteratingException . ці ёсць зэканоміць шмат блытаніны, паколькі резьб паралелізм не мае нічога агульнага з памылкай. Гэта далёка не першы падобны пытанне аб SO!
дададзена аўтар yshavit, крыніца
Гэта выключэнне павінна было назваць ModificationWhileIteratingException . ці ёсць зэканоміць шмат блытаніны, паколькі резьб паралелізм не мае нічога агульнага з памылкай. Гэта далёка не першы падобны пытанне аб SO!
дададзена аўтар yshavit, крыніца

8 адказы

Пры выкарыстанні итератора <�моцны> ня выдаліць з спісу, замест гэтага выкарыстоўвайце Iterator.remove() метад

while (it.hasNext() && it2.hasNext())  {

        Ordered o1 = it.next();
        Ordered o2 = it2.next();
        Ordered o = null;
        if(o1.value() > o2.value()){
            o = o1;
            it.remove();
            it2.remove();
        }
        else{
            o = o2;
            it.remove();
            it2.remove();

        }
        result.add(o);
}
8
дададзена
Гэта не лагічна эквівалентна кодзе OP ст. OP хоча, каб выдаліць аб з гэта і IT2 , а не бягучы элемент кожнага итератора.
дададзена аўтар Ted Hopp, крыніца
Праўда .. я ўвагнутасць звярнуць увагу на логіку, проста хацеў перадаць, што трэба выкарыстоўваць метад выдаліць з итератора. Дзякуй за ўказанне яго.
дададзена аўтар sanbhat, крыніца
+1 Выдатны адказ.
дададзена аўтар eternay, крыніца

Адзіны спосаб змяніць калекцыю ў той час як ітэрацыі праз яго з итератором праз сам итератор. Так як вы хочаце змяніць абедзве калекцыі, выдаліўшы элемент, які не можа быць бягучых элементам для аднаго з итераторов, вы не можаце выкарыстоўваць Iterator.remove() . Я рэкамендую назапашваючы набор элементаў, якія трэба выдаліць, а затым рабіць усё гэта пасля таго, як ітэрацыі завершаны. Так як вы ўжо назапашваюцца ў вынік , вы можаце выкарыстоўваць гэта:

while (it.hasNext() && it2.hasNext())  {

    Ordered o1 = it.next();
    Ordered o2 = it2.next();
    Ordered o = o1.value() > o2.value() ? o1 : o2;
    result.add(o);
}
rankedList.removeAll(result);
rankedList2.removeAll(result);
0
дададзена

Адзіны спосаб змяніць калекцыю ў той час як ітэрацыі праз яго з итератором праз сам итератор. Так як вы хочаце змяніць абедзве калекцыі, выдаліўшы элемент, які не можа быць бягучых элементам для аднаго з итераторов, вы не можаце выкарыстоўваць Iterator.remove() . Я рэкамендую назапашваючы набор элементаў, якія трэба выдаліць, а затым рабіць усё гэта пасля таго, як ітэрацыі завершаны. Так як вы ўжо назапашваюцца ў вынік , вы можаце выкарыстоўваць гэта:

while (it.hasNext() && it2.hasNext())  {

    Ordered o1 = it.next();
    Ordered o2 = it2.next();
    Ordered o = o1.value() > o2.value() ? o1 : o2;
    result.add(o);
}
rankedList.removeAll(result);
rankedList2.removeAll(result);
0
дададзена

Адзіны спосаб змяніць калекцыю ў той час як ітэрацыі праз яго з итератором праз сам итератор. Так як вы хочаце змяніць абедзве калекцыі, выдаліўшы элемент, які не можа быць бягучых элементам для аднаго з итераторов, вы не можаце выкарыстоўваць Iterator.remove() . Я рэкамендую назапашваючы набор элементаў, якія трэба выдаліць, а затым рабіць усё гэта пасля таго, як ітэрацыі завершаны. Так як вы ўжо назапашваюцца ў вынік , вы можаце выкарыстоўваць гэта:

while (it.hasNext() && it2.hasNext())  {

    Ordered o1 = it.next();
    Ordered o2 = it2.next();
    Ordered o = o1.value() > o2.value() ? o1 : o2;
    result.add(o);
}
rankedList.removeAll(result);
rankedList2.removeAll(result);
0
дададзена

Адзіны спосаб змяніць калекцыю ў той час як ітэрацыі праз яго з итератором праз сам итератор. Так як вы хочаце змяніць абедзве калекцыі, выдаліўшы элемент, які не можа быць бягучых элементам для аднаго з итераторов, вы не можаце выкарыстоўваць Iterator.remove() . Я рэкамендую назапашваючы набор элементаў, якія трэба выдаліць, а затым рабіць усё гэта пасля таго, як ітэрацыі завершаны. Так як вы ўжо назапашваюцца ў вынік , вы можаце выкарыстоўваць гэта:

while (it.hasNext() && it2.hasNext())  {

    Ordered o1 = it.next();
    Ordered o2 = it2.next();
    Ordered o = o1.value() > o2.value() ? o1 : o2;
    result.add(o);
}
rankedList.removeAll(result);
rankedList2.removeAll(result);
0
дададзена

Вы не можаце перабіраць на Collection і змяніць яго ў той жа самы час.

0
дададзена

Вы не можаце перабіраць на Collection і змяніць яго ў той жа самы час.

0
дададзена

Вы не можаце перабіраць на Collection і змяніць яго ў той жа самы час.

0
дададзена