Tôi có thể sao chép sâu bản đồ bản đồ trong Groovy như thế nào? Các khóa bản đồ là Strings hoặc Ints. Các giá trị là Strings, Primitive Objects hoặc các bản đồ khác, theo cách đệ quy.Bản đồ sâu Bản đồ trong Groovy
Trả lời
Một cách dễ dàng là thế này:
// standard deep copy implementation
def deepcopy(orig) {
bos = new ByteArrayOutputStream()
oos = new ObjectOutputStream(bos)
oos.writeObject(orig); oos.flush()
bin = new ByteArrayInputStream(bos.toByteArray())
ois = new ObjectInputStream(bin)
return ois.readObject()
}
Tôi sợ bạn phải thực hiện theo cách clone
. Bạn có thể cung cấp cho Apache Commons Lang SerializationUtils một thử
Tôi khá mới mẻ đối với Groovy. Tôi có thể sai. –
Bản sao dường như hoạt động tốt với bản đồ. Nhưng ngay khi bạn mang những vật thể phức tạp hơn vào cảnh, nó cũng không hoạt động, bởi vì nó là một bản sao nông. Bản sao sâu của Ayman là nhanh và hoạt động cho các đối tượng mà tôi đã thử (bao gồm cả ConfigObject). – noumenon
Tôi vừa mới trúng vấn đề này là tốt, và tôi chỉ tìm thấy:
deepCopy = evaluate(original.inspect())
Mặc dù tôi đã được mã hóa trong Groovy trong ít hơn 12 giờ, tôi tự hỏi nếu có thể có một số vấn đề đáng tin cậy với việc sử dụng evaluate
. Ngoài ra, ở trên không xử lý các dấu gạch chéo ngược. Điều này:
deepCopy = evaluate(original.inspect().replace('\\','\\\\'))
.
Cảm ơn bạn đã đề cập đến việc kiểm tra. Tôi đã tìm kiếm các lứa tuổi cho một tương đương Groovy của repr của Python! Để nghĩ rằng nó đã có tất cả cùng ... – Tobia
Làm việc cho tôi khi chỉnh sửa docker-compose.yml với groovy và jenkins. Cảm ơn! (đã thêm nhận xét này để tìm kiếm google dễ dàng hơn) –
Để đi sâu về sao chép từng thành viên trong một lớp, newInstance() tồn tại cho các đối tượng Lớp. Ví dụ:
foo = ["foo": 1, "bar": 2]
bar = foo.getClass().newInstance(foo)
foo["foo"] = 3
assert(bar["foo"] == 1)
assert(foo["foo"] == 3)
Xem http://groovy-lang.org/gdk.html và điều hướng đến java.lang, Class và cuối cùng là quá tải phương thức mớiInstance.
CẬP NHẬT:
Ví dụ tôi có ở trên là cuối cùng một ví dụ về một bản sao cạn, nhưng những gì tôi thực sự có nghĩa là nói chung, bạn hầu như luôn luôn phải xác định riêng đáng tin cậy Logic bản sao sâu của bạn, với có lẽ sử dụng phương thức newInstance(), nếu phương thức clone() là không đủ. Dưới đây là một số cách để thực hiện điều đó:
import groovy.transform.Canonical
import groovy.transform.AutoClone
import static groovy.transform.AutoCloneStyle.*
// in @AutoClone, generally the semantics are
// 1. clone() is called if property implements Cloneable else,
// 2. initialize property with assignment, IOW copy by reference
//
// @AutoClone default is to call super.clone() then clone() on each property.
//
// @AutoClone(style=COPY_CONSTRUCTOR) which will call the copy ctor in a
// clone() method. Use if you have final members.
//
// @AutoClone(style=SIMPLE) will call no arg ctor then set the properties
//
// @AutoClone(style=SERIALIZATION) class must implement Serializable or
// Externalizable. Fields cannot be final. Immutable classes are cloned.
// Generally slower.
//
// if you need reliable deep copying, define your own clone() method
def assert_diffs(a, b) {
assert a == b // equal objects
assert ! a.is(b) // not the same reference/identity
assert ! a.s.is(b.s) // String deep copy
assert ! a.i.is(b.i) // Integer deep copy
assert ! a.l.is(b.l) // non-identical list member
assert ! a.l[0].is(b.l[0]) // list element deep copy
assert ! a.m.is(b.m) // non-identical map member
assert ! a.m['mu'].is(b.m['mu']) // map element deep copy
}
// deep copy using serialization with @AutoClone
@Canonical
@AutoClone(style=SERIALIZATION)
class Bar implements Serializable {
String s
Integer i
def l = []
def m = [:]
// if you need special serialization/deserialization logic override
// writeObject() and/or readObject() in class implementing Serializable:
//
// private void writeObject(ObjectOutputStream oos) throws IOException {
// oos.writeObject(s)
// oos.writeObject(i)
// oos.writeObject(l)
// oos.writeObject(m)
// }
//
// private void readObject(ObjectInputStream ois)
// throws IOException, ClassNotFoundException {
// s = ois.readObject()
// i = ois.readObject()
// l = ois.readObject()
// m = ois.readObject()
// }
}
// deep copy by using default @AutoClone semantics and overriding
// clone() method
@Canonical
@AutoClone
class Baz {
String s
Integer i
def l = []
def m = [:]
def clone() {
def cp = super.clone()
cp.s = s.class.newInstance(s)
cp.i = i.class.newInstance(i)
cp.l = cp.l.collect { it.getClass().newInstance(it) }
cp.m = cp.m.collectEntries { k, v ->
[k.getClass().newInstance(k), v.getClass().newInstance(v)]
}
cp
}
}
// assert differences
def a = new Bar("foo", 10, ['bar', 'baz'], [mu: 1, qux: 2])
def b = a.clone()
assert_diffs(a, b)
a = new Baz("foo", 10, ['bar', 'baz'], [mu: 1, qux: 2])
b = a.clone()
assert_diffs(a, b)
Tôi đã sử dụng @Canonical
cho phương thức equals() và tuple ctor. Xem groovy doc Chapter 3.4.2, Code Generation Transformations.
Một cách khác để thực hiện sao chép sâu là sử dụng mixin. Hãy nói rằng bạn muốn một lớp hiện có để có chức năng sao chép sâu:
class LinkedHashMapDeepCopy {
def deep_copy() {
collectEntries { k, v ->
[k.getClass().newInstance(k), v.getClass().newInstance(v)]
}
}
}
class ArrayListDeepCopy {
def deep_copy() {
collect { it.getClass().newInstance(it) }
}
}
LinkedHashMap.mixin(LinkedHashMapDeepCopy)
ArrayList.mixin(ArrayListDeepCopy)
def foo = [foo: 1, bar: 2]
def bar = foo.deep_copy()
assert foo == bar
assert ! foo.is(bar)
assert ! foo['foo'].is(bar['foo'])
foo = ['foo', 'bar']
bar = foo.deep_copy()
assert foo == bar
assert ! foo.is(bar)
assert ! foo[0].is(bar[0])
Hoặc loại (một lần nữa thấy groovy doc) nếu bạn muốn ngữ nghĩa sao chép sâu dựa trên một số loại bối cảnh thời gian chạy:
import groovy.lang.Category
@Category(ArrayList)
class ArrayListDeepCopy {
def clone() {
collect { it.getClass().newInstance(it) }
}
}
use(ArrayListDeepCopy) {
def foo = ['foo', 'bar']
def bar = foo.clone()
assert foo == bar
assert ! foo.is(bar)
assert ! foo[0].is(bar[0]) // deep copying semantics
}
def foo = ['foo', 'bar']
def bar = foo.clone()
assert foo == bar
assert ! foo.is(bar)
assert foo[0].is(bar[0]) // back to shallow clone
- 1. Lặp qua Bản đồ trong Groovy?
- 2. đồ Groovy và bản đồ Java trên Generics
- 3. AutoMapper - lập bản đồ độ sâu
- 4. Giải quyết Groovy Bản đồ lớp
- 5. Bản đồ bản đồ - cách giữ bản đồ bên trong làm bản đồ?
- 6. Bản đồ + bản đồ choropleth trong R
- 7. Sắp xếp bản đồ trong bản đồ theo giá trị
- 8. Phím Bản đồ là Đối tượng hay không trong Groovy?
- 9. Phương thức bản đồ Groovy của bộ sưu tập
- 10. Groovy có phương pháp hợp nhất 2 bản đồ không?
- 11. để tạo Bản đồ từ Danh sách theo kiểu groovy?
- 12. Tại sao bản đồ của Groovy không có metaClass?
- 13. Chuyển đổi một vector của bản đồ tới bản đồ bản đồ trong Clojure
- 14. Bản đồ trong Guava
- 15. Sắp xếp bản đồ Grails trên nhiều trường :: Groovy sắp xếp trên nhiều mục nhập bản đồ
- 16. Cách trừ một danh sách các phím bản đồ từ một bản đồ khác và lấy bản đồ mới (bản đồ A - mab B = bản đồ C)
- 17. bản đồ so với hành vi của bản đồ
- 18. Bản đồ chi tiết bản đồ địa điểm mới
- 19. Bản đồ một mục duy nhất của một bản đồ
- 20. Chuyển đổi Bản đồ Java thành Bản đồ Javascript
- 21. Bản đồ Jquery Bings Bản đồ Json tải lại
- 22. jVectorNhập bản đồ (thế giới) kích thước bản đồ
- 23. Bản đồ cấu trúc dữ liệu Bản đồ
- 24. Bản đồ tổ chức bản đồ tự tổ chức (SOM)
- 25. ggplot2: Bản đồ nhiệt nhanh Bản đồ, định hình lại?
- 26. Bản đồ giao dịch với Bản đồ đồng bộ
- 27. Làm cách nào để tạo ra bản đồ bản đồ?
- 28. bản đồ vectơ trong STL?
- 29. Bản đồ đôi trong haskell?
- 30. Bản đồ băm trong Python
Tuyệt vời. Tôi đang sử dụng điều này để sao chép sâu một ConfigObject groovy như clone() chỉ làm một bản sao nông. Bản sao nông không đủ trên một ConfigObject cho các nhu cầu của tôi. Cảm ơn. – noumenon
Điều này là khá tuyệt vời –
Gonna phải nhớ điều này! –