Updating groovy object fields from the map

In groovy, we can easily create objects from maps and automatically fill in the appropriate fields:

def myAddress = new Address([street:"King street", number:"1200"]) 

Is it also possible to update an existing object from a map without recreating it? Sort of...

 myAddress.update([zip: "30555050", city: "London"]) 
+6
source share
2 answers

You can use object."${variable}" accessors for this:

 map.each { key, value -> object."${key}" = value } 

Then you can create a method that does this and set it to Object.metaClass, and it will be available everywhere:

 @Canonical class MapSet { String name int count static def setAttributesFromMap(Object o, Map<String, Object> map) { map.each { key, value -> o."${key}" = value } } static void main(String[] args) { Object.metaClass.update = { setAttributesFromMap delegate, it } def o = new MapSet([ name: "foo", count: 5 ]) assert o.name == "foo" assert o.count == 5 o.update([ name: "bar", count: 6 ]) assert o.name == "bar" assert o.count == 6 } } 
+7
source

You can use the InvokeHelper category and setProperties , here is a short example:

 import groovy.transform.EqualsAndHashCode import groovy.transform.ToString import org.codehaus.groovy.runtime.InvokerHelper @EqualsAndHashCode @ToString class Address { String street String number String city } Address mainAddress = new Address(street: 'Test', number: '2B', city: 'London') use InvokerHelper, { mainAddress.setProperties([street: 'Lorem', number: 'Ipsum']) } assert mainAddress.street == 'Lorem' assert mainAddress.number == 'Ipsum' assert mainAddress.city == 'London' 

Although, if you can avoid the modified objects, this is best for you. Otherwise, you need to think about thread safety so as not to run into concurrency issues. You can use the previous example to create a static method that expects 2 arguments: an existing object and a property map for updating. As a result, you get a new instance containing the updated fields. You can also make your class immutable.

+3
source

Source: https://habr.com/ru/post/985093/


All Articles