在groovy中复制列表列表

时间:2012-11-09 10:16:24

标签: groovy

我想执行一个副本并获取两个不同的对象,这样我就可以在不影响原件的情况下处理副本。

我有这段代码(groovy 2.0.5):

def a = [[1,5,2,1,1], ["one", "five", "two", "one", "one"]]
def b = a
b.add([6,6,6,6,6,6])
println a
println b

产生:

[[1, 5, 2, 1, 1], [one, five, two, one, one], [6, 6, 6, 6, 6, 6]]
[[1, 5, 2, 1, 1], [one, five, two, one, one], [6, 6, 6, 6, 6, 6]]

似乎b和a实际上是同一个对象

我可以用这种方式修复它:

def a = [[1,5,2,1,1], ["one", "five", "two", "one", "one"]]
def b = []

a.each {
    b.add(it)
}

b.add([6,6,6,6,6])
println a
println b

产生我想要的结果:

[[1, 5, 2, 1, 1], [one, five, two, one, one]]
[[1, 5, 2, 1, 1], [one, five, two, one, one], [6, 6, 6, 6, 6]]

但是现在看看这个,我想要原始对象和具有唯一和有序元素的副本:

def a = [[1,5,2,1,1], ["one", "five", "two", "one", "one"]]
def b = a

b.each {
    it.unique().sort()
}

println a
println b

产生:

[[1, 2, 5], [five, one, two]]
[[1, 2, 5], [five, one, two]]

如果我这次尝试相同的修复它不起作用:

def a = [[1,5,2,1,1], ["one", "five", "two", "one", "one"]]
def b = []

a.each { 
    b.add(it)
}

b.each {
    it.unique().sort()
}

println a
println b

仍然产生:

[[1, 2, 5], [five, one, two]]
[[1, 2, 5], [five, one, two]]

发生了什么事?

2 个答案:

答案 0 :(得分:5)

只需调用b = ab设置为与a

相同的列表实例(包含相同的列表实例)

使用a.each { b.add(it) }调用第二个方法意味着b指向不同的List实例,但b的内容与a

中的列表相同

您需要的是:

def b = a*.collect()

b.each {
  it.unique().sort()
}

因此a*.collect()a

中的每个列表创建了一个新列表实例

您也可以在一行中执行此操作:

def b = a*.unique( false )*.sort( false ) 

false传递给uniquesort stop those method changing the original lists,并强制他们返回新的列表实例。

(事实上你们中间的观察者会注意到sort不需要false传递给它,因为unique已经有了一个新的实例)

答案 1 :(得分:2)

Groovy有Collection#collectNested,这是#collect的递归形式。这将创建任意深度列表的副本。在1.8.1版之前,它被称为#collectAll

final a = [
    'a', [ 'aa', 'ab', [ 'aba', 'abb', 'abc' ], 'ac', 'ad' ], 'b', 'c', 'd', 'e'
]

final b = a.collectNested { it }
b[0] = 'B'

final c = a.collectNested { it * 2 }
c[0] = 'C'

assert a as String ==
    '[a, [aa, ab, [aba, abb, abc], ac, ad], b, c, d, e]'

assert b as String ==
    '[B, [aa, ab, [aba, abb, abc], ac, ad], b, c, d, e]'

assert c as String ==
    '[C, [aaaa, abab, [abaaba, abbabb, abcabc], acac, adad], bb, cc, dd, ee]'