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?
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 byofNullable(T)
) the result of applying the given mapping function to the value, otherwise returns an emptyOptional
.
So that we can finally:
private /*static*/ Optional<Integer> checkNullAge(String age) {
// try {
return Optional.ofNullable(age).map(Integer::valueOf);
// } catch (NumberFormatException nfE) ...
}