在groovy中复制列表列表

Luc*_*uca 5 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
Run Code Online (Sandbox Code Playgroud)

产生:

[[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]]
Run Code Online (Sandbox Code Playgroud)

看起来像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
Run Code Online (Sandbox Code Playgroud)

产生我想要的结果:

[[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]]
Run Code Online (Sandbox Code Playgroud)

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

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

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

println a
println b
Run Code Online (Sandbox Code Playgroud)

产生:

[[1, 2, 5], [five, one, two]]
[[1, 2, 5], [five, one, two]]
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

仍然产生:

[[1, 2, 5], [five, one, two]]
[[1, 2, 5], [five, one, two]]
Run Code Online (Sandbox Code Playgroud)

这是怎么回事 ?

tim*_*tes 5

只是将b = a集合调用b为与列表相同的实例(包含相同的列表实例)a

使用a.each { b.add(it) }均值b 调用第二种方法指向List的不同实例,但内容b与列表中的列表相同a

你需要的是:

def b = a*.collect()

b.each {
  it.unique().sort()
}
Run Code Online (Sandbox Code Playgroud)

因此,a*.collect()为每个列表创建一个列表的新实例a

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

def b = a*.unique( false )*.sort( false ) 
Run Code Online (Sandbox Code Playgroud)

传递falseuniquesort 阻止那些方法改变原来的列表,并强迫他们返回新的列表实例.

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