I have the following class
@Builder
public class User {
private String userName;
private String email;
private String device;
private String deviceType;
}
I want to set the value deviceType
based on the inputs I get for device
. Is that possible with Builder
? I don't want to set the value of deviceType
directly.
Example
if (device == "iPhone") {
this.deviceType = "mobile"
} else if (device == "Kindle") {
this.deviceType = "tablet"
} .. and so on
Ideally, I want this to be done in the constructor one time
I am currently building the object like this but I am not sure how to initialize the userEmail
field.
User.builder()
.userName("sample-username)
.email("sample-email")
.device("iPhone")
.build();
You could use Lombok's GetterLazy
From the doc,
You can let lombok generate a getter which will calculate a value once, the first time this getter is called, and cache it from then on. [...] To use this feature, create a private final variable, initialize it with the expression that's expensive to run, and annotate your field with @Getter(lazy=true). The field will be hidden from the rest of your code, and the expression will be evaluated no more than once, when the getter is first called.
@Builder
private static class User {
private String userName;
private String email;
private String device;
@Getter(lazy=true)
private final String deviceType = deriveDeviceType();
private String deriveDeviceType() {
Objects.requireNonNull(device);
switch (device) {
case "iPhone": return "mobile";
case "Kindle": return "tablet";
// and so on...
}
throw new RuntimeException("Invalid value set for device");
}
}
With this, the deviceType
field won't be available to be set via the builder.
Note that the field will be initialized only when the getter (getDeviceType()
) is called and not when the field is accessed directly.
User u = User.builder()
.userName("test-name")
.email("test-email")
.device("Kindle")
.build();
System.out.println(user.getDeviceType()); //tablet
Since it is possible to pass an invalid value for device, I suggest you to look into using enums to model device
and deviceType
(if possible).