仍在学习 Groovy 的诀窍,这个问题从昨晚开始就一直困扰着我。不知道为什么它会抛出并发模式异常...(Java 1.6,Groovy 1.8.4)
我有一个键列表...
[1,2,3,4,5,6,7,8,9,10,11,12,13]
我使用自定义函数整理列表 partitionList(keys,3)
我从 here 得到(不能使用 java.List.Collate,1.8.6 上不行)
现在我得到了一个列表列表......
[[0,1,2],[3,4,5],[6,7,8],[9,10,11],[12,13]]
如果创建的子列表数量是奇数,我会删除最后一个子列表 [12,13]
并将其 key 重新分配到按顺序开始的其他子列表中,创建...
[[0,1,2,12],[3,4,5,13],[6,7,8],[9,10,11]]
迭代最后一个子列表的值时发生异常。不知道为什么,因为我正在迭代一个列表并在该循环中更改一个完全不同的列表...
更新:
有趣......如果我不使用paritionList()
函数,替换
def keyRanges = partitionList( keys, 3)
带有明确的列表列表...
def keyRanges = [[0,1,2],[3,4,5],[6,7,8],[9,10,11],[12,13]]
问题就消失了。所以我相信partitionList()函数正在做一些导致异常的事情
class CollateListTest {
static main(args) {
def keys = (0..13).toList()
//partition the keys into a list of lists
def keyRanges = partitionList( keys, 3)
println 'Key range sets...'
for( keyRange in keyRanges)
println keyRange
//if odd number of partitions,
//remove last sub list and redistribute values over other lists
if( (keyRanges.size() % 2) != 0){
def lastKeyRange = keyRanges.remove( keyRanges.size() - 1 )
println 'removed range: ' + lastKeyRange
// ** EXCEPTION HERE **
lastKeyRange.eachWithIndex{ k, index ->
println 'adding: ' + k
keyRanges[ index % keyRanges.size()].add( k)
}
}
}
//from stackoverflow.com/questions/2924395/
static def partitionList(list, size) {
def partitions = []
int partitionCount = list.size() / size
partitionCount.times { partitionNumber ->
def start = partitionNumber * size
def end = start + size - 1
partitions << list[start..end]
}
if (list.size() % size) partitions << list[partitionCount * size..-1]
return partitions
}
}
最佳答案
您使用的 partitionList
方法使用 List.getAt(Range) 分割列表。 。这将返回原始列表的 View ,但不会复制数据,因此对子列表的任何修改也会影响原始列表。
这意味着 lastKeyRange
与 keyRanges
共享数据,并且添加到子列表之一会间接影响您正在迭代的子列表。无需修改子列表,只需创建一个新子列表即可。例如:
if( (keyRanges.size() % 2) != 0){
def lastKeyRange = keyRanges.remove( keyRanges.size() - 1 )
println 'removed range: ' + lastKeyRange
lastKeyRange.eachWithIndex{ k, index ->
println 'adding: ' + k
def newRange = []
newRange.addAll(keyRanges[ index % keyRanges.size()])
newRange.add(k)
keyRanges[ index % keyRanges.size()] = newRange
}
}
关于arrays - Groovy,整理列表导致并发修改异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9536552/