I want to perform a copy and get two different objects so that I can work on the copy without impacting the original.
I have this code (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
that produces:
[[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]]
seems like b and a are actually the same object
I can fix it in this way:
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
that produces my wanted result:
[[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]]
But now look at this, where I want the original object and a copy with unique and sorted elements:
def a = [[1,5,2,1,1], ["one", "five", "two", "one", "one"]]
def b = a
b.each {
it.unique().sort()
}
println a
println b
that produces:
[[1, 2, 5], [five, one, two]]
[[1, 2, 5], [five, one, two]]
If I try the same fix this time it doesn’t work:
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
that still produces:
[[1, 2, 5], [five, one, two]]
[[1, 2, 5], [five, one, two]]
What’s going on ?
Just calling
b = asetsbto being the same instance of the list (containing the same list instances) asaCalling the second method with the
a.each { b.add(it) }means b points to a different instance of List, but the contents ofbare the same instances of lists as inaWhat you need is something like:
So the
a*.collect()makes a new instance of a list for each list inaYou can also do this in one line:
Passing
falsetouniqueandsortstop those method changing the original lists, and force them to return new list instances.(Indeed the observant amongst you will notice that the
sortdoes not needfalsepassed to it, as we already have a new instance thanks tounique)