What's the most efficient way on java 11 to null check multiple fields from the same object? I was going with optionals but I don't understand how to use them with more fields of the same object
Map<String, NestedQuery> nested = new HashMap<>();
if (getSentDate() != null) {
if (getSentDate().getFrom() != null && getSentDate().getTo() != null) {
nested.put(...);
}
}
return nested;
In my case getSentdate()
returns an object that has getFrom()
and getTo()
that are values that may or may not be null
I tried with this but the use of.ifPresent inside an if clause is a big no no
Map<String, NestedQuery> nested = new HashMap<>();
Optional.ofNullable(getSentDate())
.ifPresent(sentDate -> {
Optional<String> from = Optional.ofNullable(sentDate.getFrom());
Optional<String> to = Optional.ofNullable(sentDate.getTo());
if(from.isPresent() && to.isPresent()){
nested.put(...);
}
});
return nested;
As it has been said in the comments above your original code is actually quite efficient (we probably need some criteria for effectiveness):
if (getSentDate() != null) {
if (getSentDate().getFrom() != null && getSentDate().getTo() != null) {
However if you really want to use an Optional
to eliminate some of the null checks it is enough to use just one:
Optional.ofNullable(getSentDate())
.filter(sentDate -> Objects.nonNull(sentDate.getFrom()))
.filter(sentDate -> Objects.nonNull(sentDate.getTo()))
.ifPresent(date -> nested.put(...));
in this case .ifPresent(date -> nested.put(...))
is executed only when all 3 conditions are met: getSentDate()
is not null
, sentDate.getFrom()
is not null
and sentDate.getTo()
is not null
as well. However we still have a null check and we are "abusing" Objects#nonNull method since:
API Note: This method exists to be used as a Predicate, filter(Objects::nonNull)
An equivalent for this is
Optional.ofNullable(getSentDate())
.filter(sentDate -> sentDate.getFrom() != null)
.filter(sentDate -> sentDate.getTo() != null)
.ifPresent(date -> nested.put(...));
Please note as well that this actually "violates" Optional usage
API Note: Optional is primarily intended for use as a method return type where there is a clear need to represent "no result," and where using null is likely to cause errors.
Try the following, here a NestedQuery has an optional send date, and a SendDate has optional getFrom and getTo values. You can use ifpresent ans ispresent to check if the value is present
private interface SendDate {
Optional<Object> getFrom();
Optional<Object> getTo();
}
private interface NestedQuery {
public Optional<SendDate> getSendDate();
}
private static NestedQuery createNestedQuery() {
return Optional::empty;
}
public static void main(final String[] args) {
final Map<String, NestedQuery> nested = new HashMap<>();
final NestedQuery nestedQuery = createNestedQuery();
nestedQuery.getSendDate().ifPresent(sendDate -> {
if (sendDate.getFrom().isPresent() && sendDate.getTo().isPresent())
nested.put("", nestedQuery);
});
System.out.println(nested.toString());
}
Though the conditional expression using && and its short-circuiting behavior is the best you can get while dealing with multiple levels of attributes. Still, for a single level of nesting , you can easily introduce a utility which conforms none of the attributes inside are null.
@SafeVarargs
static <T> boolean noneNull(T... args) {
return Arrays.stream(args).noneMatch(Objects::isNull);
}
and use it as
if(noneNull(sentDate.getFrom(), sentDate.getTo())) {
nested.put(...)
}
and notice, there is no involvement of Optional
for this which in general is not required for a check of null objects.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.