javaoptional-chaining

Efficient way to check if a getter will return null in Java before passing to Optional?


I have a simple data class such as

@Data
@Builder
public class MyPerson implements Serializable {
    String name;
    String age; //Purposely keeping as String here
    String address;
}

After constructing the object, I want to construct an Immutable object using it with the following definition, where I know name will never be null, but age and address might:

@Value.Style(stagedBuilder = true)
@Value.Immutable
public interface MyImmutablePerson extends Serializable {
    String getName();
    Optional<Integer> getAge();
    Optional<String> getAddress();
}
    

The first person object is created, and now want to create this second Immutable object, where age and address could be null

MyImmutablePerson.builder()
    .name(myPerson.getName())
    .age(myPerson.getAge()) //Could be null!
    .address(myPerson.getAddress()) //Could be null!
    .build()
    

My thought it is that I could pass to another function to check and return an empty optional if it is null:

private Optional<Integer> checkNullAge(String age) {
    if (age.isNull()) {
        return Optional.empty()
    }
    
    return Optional.of(age);
}

In doing this, I have duplicate another class just for Strings, another class for Boolean,.... etc. which is super ineficient.

Is there a better way to do a null check and then return an empty optional?


Solution

  • return Optional.ofNullable(age);!?;)

    Returns an Optional describing the given value, if non-null, otherwise returns an empty Optional.

    For "conversion" (String->Integer) @bro proposed Optional.map()!(thx!) Which...

    If a value is present, returns an Optional describing (as if by ofNullable(T)) the result of applying the given mapping function to the value, otherwise returns an empty Optional.

    So that we can finally:

    private /*static*/ Optional<Integer> checkNullAge(String age) {
        // try {
        
        return Optional.ofNullable(age).map(Integer::valueOf);
        // } catch (NumberFormatException nfE) ...
    }