If you have no idea what can be null, or want to check everything for null, the only way is to chain calls to Optional.map:
If a value is present, apply the provided mapping function to it, and if the result is non-null, return an Optional describing the result. Otherwise return an empty Optional.
As such, if the mapper return null, an empty Optional will be returned, which allows to chain calls.
Optional.ofNullable(insight)
.map(i -> i.getValues())
.map(values -> values.get(0))
.map(v -> v.getValue())
.orElse(0);
The final call to orElse(0) allows to return the default value 0 if any mapper returned null.
How to idiomatically map() a nullable reference
Using Java 8 Optional for safe fetching from Map - Stack Overflow
Why does Optional require a non-null value?
Why exactly does Brian Goetz not recommend the use of Optional everywhere a value could be null?
If you have no idea what can be null, or want to check everything for null, the only way is to chain calls to Optional.map:
If a value is present, apply the provided mapping function to it, and if the result is non-null, return an Optional describing the result. Otherwise return an empty Optional.
As such, if the mapper return null, an empty Optional will be returned, which allows to chain calls.
Optional.ofNullable(insight)
.map(i -> i.getValues())
.map(values -> values.get(0))
.map(v -> v.getValue())
.orElse(0);
The final call to orElse(0) allows to return the default value 0 if any mapper returned null.
smth like this should work
Optional.ofNullable(insight.getValues()).map(vals -> vals.get(0)).map(v -> v.getValue())
well, according to the sample code given, as #extractFirstValueFrom do not contain neither @Nullable nor checks for null like Guava's checkNotNull(), let's assume that insight is always something. thus wrapping Optional.ofNullable(insight.getValues()) into Option would not result with NPE. then call chain of transformations is composed (each results with Optional) that lead to result Optional<Integer> that might be either Some or None.
I'm trying to find the idiomatic way of applying a mapping on something which may be null, in a Java 17+ codebase, but where there are sometimes nulls around.
Imagine you have a method like this, where I want to return a path to some file, or null:
Path theSomethingPathOrNull() {
File theFile = ... something elaborate which may give null
return theFile.toPath(); // Obviously a problem
}Now, if only it were Groovy, and I could use:
return theFile?.toPath()
But alas, this is just Java. Back in the day, we'd have done it with:
return theFile != null ? theFile.toPath() : null;
But people not used to C would have frowned in the code review. Yeah, they sometimes do.
Now, since this is for "modern" Java, I suppose the idiomatic way would be:
return Optional.ofNullable(theFile).map(File::toPath).orElse(null);
That's a mouthful. Even with a static import of Optional.ofNullable, it seems noisy.
I could make a nice little helper like this somewhere:
public static <T, U> U mapNullable(T obj, Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
return obj != null ? mapper.apply(obj) : null;
}Then I could write:
return mapNullable(theFile, File::toPath);
That would save a few keystrokes, but would people understand it?
Does this helper exist in a commonly used library already?
Any ideas or bikeshed suggestions?
P.S.: I know that the real answer is that I should be returning an Optional instead, but that's not always an option.
Building on Alexander Ivanchenko's answer, you could get the first non-null value from the map based on a series of alternate keys:
Copypublic static Optional<String> getValue(Map<String, String> map,
String keyA, String... keys) {
Optional<String> result = Optional.ofNullable(map.get(keyA));
for (String key : keys) {
if (result.isPresent()) break;
result = result.or(() -> Optional.ofNullable(map.get(key)));
}
return result;
}
You could use the getOrDefault method of map, but something like
Copymap.getOrDefault("keyA", map.getOrDefault("keyB", map.get("keyC")))
seems overly specific and complicated, and you still have to deal with the fact that neither keyA nor keyB nor keyC might be present, so you might still get null, and this has the performance penalty of looking up all three values from the map no matter which is returned.
It also only works for three keys.
No. There is no special integration of Optional with Maps.
More to the point, Optional does not support null values. Assuming that by "nullable map" you mean "a map that can contain null values", you can't possibly use Optional to distinguish between "null values that are in your map" and "values that aren't in your map at all." There is absolutely no way to use Optional helpfully in this scenario.