Groovy中,整理列表导致concurrentmodification例外 [英] Groovy, collating list causes concurrentmodification exception
问题描述
仍在学习使用Groovy的绳索,这个问题我绊倒从昨晚起。不知道为什么它的投掷concurrentmod例外...(Java 1.6的,Groovy的1.8.4)
我有键列表... [1,2,3,4,5,6,7,8,9,10,11,12,13]
我整理使用自定义函数 partitionList(按键,3)
我从<一拿到名单href=\"http://stackoverflow.com/questions/2924395/groovy-built-in-to-split-an-array-into-equal-sized-subarrays/2926548#2926548\">here (不能用java.List.Collate,而不是1.8.6)
现在我有一个列表的列表... [0,1,2],[3,4,5],[6,7,8],[9,10,11],[12,13]
如果创建子列表的个数是奇数,我删除了最后一个子列表 [12,13]
和重新分配之间的其他子列表,以便开始它的键,创造...
[0,1,2,12],[3,4,5,13],[6,7,8],[9,10,11]
迭代的最后一个子列表的值时,会发生的异常。不知道为什么,因为我遍历一个列表,并在循环改变一个完全不同的列表...
更新:
有趣的....如果我不使用 paritionList()
函数替换,高清keyRanges = partitionList(按键,3)
以列表的明确列表...高清keyRanges = [[0,1,2],[3,4,5],[6,7,8],[9,10,11],[12,13]
问题消失。所以我带领相信的partitionList()函数做的事情是造成异常
类CollateListTest { 静态main(参数){
DEF键=(0..13).toList() //按键分割成一个列表的列表
高清keyRanges = partitionList(按键,3)
的println重点范围套......
对于(KEYRANGE在keyRanges)
的println KEYRANGE //如果奇数分区,
//删除最后一个子列表并重新分配在其他列表值
如果((keyRanges.size()%2)!= 0){
高清lastKeyRange = keyRanges.remove(keyRanges.size() - 1)
的println'去除范围:'+ lastKeyRange // ** EXCEPTION这里**
lastKeyRange.eachWithIndex {K,指数 - &GT;
的println,并称:+ K
keyRanges [索引%keyRanges.size()。添加(K)
}
}
} //从stackoverflow.com/questions/2924395/
静态高清partitionList(列表,大小){
DEF分区= []
INT partitionCount =则为list.size()/大小 partitionCount.times {分区编号 - &GT;
高清启动=分区编号*尺寸
高清结束=启动+大小 - 1
分区&LT;&LT;列表[start..end]
} 如果(则为list.size()%的大小)分区&LT;&LT;列表[partitionCount *尺寸..- 1]
回分区
}
}
你使用了分裂列表用的 partitionList 方法=HTTP:/ /groovy.$c$chaus.org/groovy-jdk/java/util/List.html#getAt%28groovy.lang.Range%29相对=nofollow> List.getAt(范围)。这将返回一个视图到原来的名单,但不复制数据,所以任何修改子列表也影响到原来的。
这意味着, keyRanges
lastKeyRange
共享数据,并增加了子列表中的一个间接影响的子列表你迭代。而不是修改子表,只需创建一个新的。例如:
IF((keyRanges.size()%2)!= 0){
高清lastKeyRange = keyRanges.remove(keyRanges.size() - 1)
的println'去除范围:'+ lastKeyRange lastKeyRange.eachWithIndex {K,指数 - &GT;
的println,并称:+ K
高清newRange = []
newRange.addAll(keyRanges [索引%keyRanges.size()])
newRange.add(K)
keyRanges [索引%keyRanges.size()] = newRange }
}
Still learning the ropes with Groovy, this problem has tripped me up since last night. Not sure why it's throwing concurrentmod exception...(Java 1.6, Groovy 1.8.4)
I have a list of keys...
[1,2,3,4,5,6,7,8,9,10,11,12,13]
I collate the list using a custom function partitionList(keys,3)
I got from here (can't use java.List.Collate, not on 1.8.6)
Now I've got a list of lists...
[[0,1,2],[3,4,5],[6,7,8],[9,10,11],[12,13]]
If the number of sub-lists created is odd, I remove the last sub list [12,13]
and redistribute its keys amongst the other sub lists starting in order, creating...
[[0,1,2,12],[3,4,5,13],[6,7,8],[9,10,11]]
The exception occurs when iterating the values of the last sub list. Not sure why since I'm iterating a list and changing an entirely different list in that loop...
UPDATE:
Interesting....if I don't use the paritionList()
function, replacing
def keyRanges = partitionList( keys, 3)
with an explicit list of lists...
def keyRanges = [[0,1,2],[3,4,5],[6,7,8],[9,10,11],[12,13]]
the problem disappears. So I'm lead to believe the partitionList() function is doing something that's causing the exception
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
}
}
The partitionList
method you're using splits up the list with List.getAt(Range). This returns a view into the original list, but doesn't copy the data, so any modifications to the sublist also affect the original.
This means that lastKeyRange
shares data with keyRanges
, and that adding to one of the sublists indirectly affects the sublist you are iterating over. Rather than modifying the sublist, just create a new one. For example:
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
}
}
这篇关于Groovy中,整理列表导致concurrentmodification例外的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!