Groovy中,整理列表导致concurrentmodification例外 [英] Groovy, collating list causes concurrentmodification exception

查看:229
本文介绍了Groovy中,整理列表导致concurrentmodification例外的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

仍在学习使用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.Collat​​e,而不是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()函数做的事情是造成异常

 类Collat​​eListTest {    静态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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆