groovy子列表删除

时间:2013-04-13 08:12:08

标签: list groovy

我有一个清单:

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

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

1 个答案:

答案 0 :(得分: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]