2012-11-09 51 views
5

Tôi muốn thực hiện một bản sao và nhận hai đối tượng khác nhau để tôi có thể làm việc trên bản sao mà không ảnh hưởng đến bản gốc.Sao chép danh sách các danh sách trong groovy

tôi có mã này (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 

sản xuất:

[[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]] 

có vẻ như b và đang thực sự cùng một đối tượng

tôi có thể sửa chữa nó theo cách này:

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 

sản xuất kết quả mong muốn của tôi:

[[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]] 

Nhưng bây giờ xem xét điều này, nơi tôi muốn các đối tượng gốc và một bản sao với độc đáo và sắp xếp các yếu tố:

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

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

println a 
println b 

sản xuất:

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

Nếu tôi cố gắng sửa lỗi lần này thì nó không hoạt động:

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 

mà vẫn sản xuất:

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

gì đang xảy ra?

+0

Tiêu đề đã chỉnh sửa vì đây là các danh sách chứ không phải mảng –

Trả lời

5

Chỉ cần gọi b = a bộ b để trở thành những ví dụ tương tự của danh sách (có chứa các trường hợp cùng một danh sách) như a

Gọi phương thức thứ hai với a.each { b.add(it) } nghĩa điểm b đến một trường hợp khác nhau của List, nhưng nội dung của b là những trường hợp tương tự của danh sách như trong a

gì bạn cần là một cái gì đó như:

def b = a*.collect() 

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

Vì vậy, các a*.collect() tạo ra một thể hiện mới của một danh sách cho mỗi danh sách trong a

Bạn cũng có thể làm điều này trong một dòng:

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

Đi qua false-uniquesortstop those method changing the original lists, và buộc họ phải trở lại mới danh sách các trường hợp.

(Trên thực tế các quan sát trong số bạn sẽ nhận thấy rằng các sort không cần false truyền cho nó, như chúng ta đã có một trường hợp mới nhờ unique)

+0

'.collectNested {}' –

2

Groovy có Collection#collectNested, đó là hình thức đệ quy của #collect. Điều này sẽ tạo ra các bản sao của danh sách độ sâu tùy ý. Trước phiên bản 1.8.1, nó được gọi là #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]' 
Các vấn đề liên quan