projectlombok / lombok

Very spicy additions to the Java programming language.
https://projectlombok.org/
Other
12.89k stars 2.39k forks source link

[FEATURE] idea with @Builder or @Accessors add Condition or Function annotation, set field value with condition #2470

Open bijialin opened 4 years ago

bijialin commented 4 years ago

problem

we use @Builder set entity field,sometimes we need set it with some condition, just like object not null ,string not empty..., if lombok can add a annotation to solve that

current example

@Builder
public class User{
   private String name;
    private String mobile;
    private String email;
}

final UserBuilder builder = User.builder().name(name);
if(null!=mobile){
   builder.mobile(mobile);
}
if(null!=email){
   builder.email(email);
}

solution

if lombok can create @Builder.Condition annotation , to auto create method like this.

@Builder
public class User{
   private String name;

   @Builder.Condition
    private String mobile;

    private String email;
}

# User class genarate code 

  public UserBuilder mobile(boolean condition, String mobile) {
    if (condition) {
      this.mobile = mobile;
    }
    return this;
  }

# use 
final UserBuilder builder = User.builder().name(name).mobile(null!=mobile,mobile);

when we use @Accessors set field value, it also same applies

Maaartinus commented 4 years ago

This feature probably wouldn't help much; the amount of code is about the same. Actually, in your example, the condition doesn't matter as mobile is null before the assignment.

In general, it could help to keep the fluent style.... however, I doubt it's worth it. Oftentimes, you could replace it by something like .mobile(Strings.nullToEmpty(mobile)) or .mobile(MoreObjects.firstNonNull(mobile, defaultMobile)) (both utils taken from Guava).

Disclaimer: I'm not a project owner.

michaelboyles commented 4 years ago

seems quite a specific use-case. consider instead

Optional.ofNullable(mobile).ifPresent(builder::setMobile)

onacit commented 4 months ago

seems quite a specific use-case. consider instead

Optional.ofNullable(mobile).ifPresent(builder::setMobile)

Good point. I searched issues to suggest a feature that a builder's invocation chain may use an Optional value.

Note that, using an Optional as a method parameter is not a good move, yet I see,

public UriComponentsBuilder#queryParamIfPresent(String name, Optional value)

which keeps invocation chaining available.

Can we generate additional setter methods take Optional which invoke original setter method when present?

        public B userId(String userId) {
            this.userId = userId;
            return this.self();
        }

        public B userIdIfPresent(Optional<String> userId) {
            userId.ifPresent(this::userId);
            return this.self();
        }
var userName = getUserName();
var userId = getUserId(); // Optional<String>
builder()
        .userName(userName)
        .userIdIfPresent(userId)
        .build();