Reputation: 335
I have a method findUrl()
that take a User
and a Permission
as parameters and queries the Database and implements some logic to find the URLs accessible to this User
in comma separated string.
I want to develop a null-safe version of this method taking same
User
and Permission
as parameters and then returning an Optional
which will be
empty if at least one of the values passed to it is empty or findUrl
method return null
. I wrote the below code but it seems like a null check based implementation and I don't see much benefit of using Optional to make code more concise.
public Optional<String> nullSafeFindUrl(User user, Permissions permissions) {
if ((Optional.ofNullable(user)).isPresent() && (Optional.ofNullable(permissions)).isPresent()) {
return Optional.ofNullable(findUrl(user.get(), permissions.get()));
} else {
return Optional.empty();
}
}
Is there a better way to do it to make code more readable ?
Upvotes: 0
Views: 893
Reputation: 335
The answer is similar to Ash but I'll add some explanation also so that it can help others
invoke flatMap on the first optional, so if this is empty, the lambda expression passed to it won’t be executed at all and this invocation will just return an empty optional.
Conversely, if the User is present, it uses it as the input of a Function returning an Optional as required by the flatMap method. The body of this function invokes a map on the second optional, so if it doesn’t contain any Permission, the Function will return an empty optional and so will the whole null- Safe method.
Finally, if both the User and the Permission are present, the lambda expression passed as argument to the map method can safely invoke the original findUrl method with them.
So after applying the above the implementation of method got reduced to single Line
public Optional<String> nullSafeFindUrl(User user, Permissions permissions) {
(Optional.ofNullable(user)).flatMap(u -> (Optional.ofNullable(permissions)).map(p -> findUrl(p, u)));
}
Upvotes: 2
Reputation: 2602
What you need is to flatmap and map in one go.
return user.flatMap(u -> permissions.map(perm -> findUrl(u, perm));
This will return an empty Optional or an optional with the return value if both are valid
Upvotes: 2