Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Build an object from an existing one using lombok

Tags:

java

lombok

People also ask

Can I use @data and @builder together?

Lombok @Data and @Builder together If you use @Data annotation alone, public required-args constructor is generated. If you are using @Data and @Builder annotations together, all-args constructor (Package access level) is generated.

What is toBuilder Lombok?

This tells Lombok to add the toBuilder() method to our Class. When we invoke the toBuilder() method, it returns a builder initialized with the properties of the instance it's called on: Widget testWidget = Widget. builder() .

What is the use of @builder annotation?

The @Builder annotation produces complex builder APIs for your classes. @Builder lets you automatically produce the code required to have your class be instantiable with code such as: Person. builder()


You can use the toBuilder parameter to give your instances a toBuilder() method.

@Builder(toBuilder=true)
class Foo {
   int x;
   ...
}

Foo f0 = Foo.builder().build();
Foo f1 = f0.toBuilder().x(42).build();

From the documentation:

If using @Builder to generate builders to produce instances of your own class (this is always the case unless adding @Builder to a method that doesn't return your own type), you can use @Builder(toBuilder = true) to also generate an instance method in your class called toBuilder(); it creates a new builder that starts out with all the values of this instance.

Disclaimer: I am a lombok developer.


Is there an easy way to create an object of Foo using the existing object as a template and changing one of it's properties? (emphasis mine)

If you really want to change a single property, then there's a nicer and more efficient way:

@With
class Band {
   String name;
   String type;
}

Band nirvana = rollingStones.withName("Nirvana");

The wither creates no garbage, but it can change just a single field. For changing many fields, you could use

withA(a).withB(b).withC(c)....

and produce tons of garbage (all intermediate results) but than toBuilder is more efficient and more natural.

NOTE: Older versions of lombok have used @Wither annotation. See beginning of documentation.


You might also want do a copy of the object using com.fasterxml.jackson.databind.ObjectMapper

@AllArgsConstructor
@Setter
class Band {
    String name;
    String type;
}

ObjectMapper objectMapper = new ObjectMapper(); //it's configurable
objectMapper.configure( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false );
objectMapper.configure( SerializationFeature.FAIL_ON_EMPTY_BEANS, false );

Band rollingStones = new Band("Rolling Stones", "Rock Band");

Band nirvana = objectMapper.convertValue( rollingStones, Band.class);
nirvana.setName("Nirvana");

it can be easily wrapped in some utility method to be used all over the project like ConvertUtils.clone(rollingStones, Band.class)