1

我有一个清单:

def clc = [[1, 15, 30, 42, 48, 100], [58, 99], [16, 61, 85, 96, 98], [2, 63, 84, 90, 91, 97], [16, 61, 85, 96], [23, 54, 65, 95], [16, 29, 83, 94], [0, 31, 42, 93], [33, 40, 51, 56, 61, 62, 64, 89, 92], [0, 63, 84, 90, 91]]

和一个子列表

def subclc = [[1, 15, 30, 42, 48, 100], [58, 99], [16, 61, 85, 96, 98], [2, 63, 84, 90, 91, 97]]

我需要从原始列表中删除子列表我这样做:

subclc.each{
   clc.remove(it)
}

但它会抛出异常Exception in thread "main" java.util.ConcurrentModificationException

我不明白问题出在哪里以及如何解决问题

4

1 回答 1

2

简短的答案:

为了获得更多的常规和不变性,保留原始列表:

def removed = clc - subclc

assert removed == [[16, 61, 85, 96], [23, 54, 65, 95], [16, 29, 83, 94], [0, 31, 42, 93], [33, 40, 51, 56, 61, 62, 64, 89, 92], [0, 63, 84, 90, 91]]

和java方式,改变原来的列表:

clc.removeAll subclc

assert clc == [[16, 61, 85, 96], [23, 54, 65, 95], [16, 29, 83, 94], [0, 31, 42, 93], [33, 40, 51, 56, 61, 62, 64, 89, 92], [0, 63, 84, 90, 91]]

长答案:

Iterator在更改列表时正在浏览列表。在这种情况下,您最好使用Iterator.remove()foreach 循环抽象出来的 . 当您使用 foreach 循环更改列表时,您会遇到迭代器使用checkForComodification(). 让迭代器显式工作:

list1 = [10,20,30,40,50,60,70,80,90]
list2 = [50,60,80]

def iter = list1.iterator()
while (iter.hasNext()) {
    def item = iter.next()
    if (list2.contains(item)) iter.remove()
}
assert list1 == [10,20,30,40,70,90]

或者您可以使用索引。请注意,您需要控制索引:

list1 = [10,20,30,40,50,60,70,80,90]
list2 = [50,60,80]

for (int i = 0; i < list1.size(); i++) {
    def item = list1[i]
    if (list2.contains(item)) { list1.remove i-- }
}
assert list1 == [10,20,30,40,70,90]
于 2013-04-13T14:29:31.610 回答