'Java 8 optional: ifPresent return object orElseThrow exception
I'm trying to make something like this:
private String getStringIfObjectIsPresent(Optional<Object> object){
object.ifPresent(() ->{
String result = "result";
//some logic with result and return it
return result;
}).orElseThrow(MyCustomException::new);
}
This won't work, because ifPresent takes Consumer functional interface as parameter, which has void accept(T t). It cannot return any value. Is there any other way to do it ?
Solution 1:[1]
Actually what you are searching is: Optional.map. Your code would then look like:
object.map(o -> "result" /* or your function */)
.orElseThrow(MyCustomException::new);
I would rather omit passing the Optional
if you can. In the end you gain nothing using an Optional
here. A slightly other variant:
public String getString(Object yourObject) {
if (Objects.isNull(yourObject)) { // or use requireNonNull instead if NullPointerException suffices
throw new MyCustomException();
}
String result = ...
// your string mapping function
return result;
}
If you already have the Optional
-object due to another call, I would still recommend you to use the map
-method, instead of isPresent
, etc. for the single reason, that I find it more readable (clearly a subjective decision ;-)).
Solution 2:[2]
Two options here:
Replace ifPresent
with map
and use Function
instead of Consumer
private String getStringIfObjectIsPresent(Optional<Object> object) {
return object
.map(obj -> {
String result = "result";
//some logic with result and return it
return result;
})
.orElseThrow(MyCustomException::new);
}
Use isPresent
:
private String getStringIfObjectIsPresent(Optional<Object> object) {
if (object.isPresent()) {
String result = "result";
//some logic with result and return it
return result;
} else {
throw new MyCustomException();
}
}
Solution 3:[3]
Use the map
-function instead. It transforms the value inside the optional.
Like this:
private String getStringIfObjectIsPresent(Optional<Object> object) {
return object.map(() -> {
String result = "result";
//some logic with result and return it
return result;
}).orElseThrow(MyCustomException::new);
}
Solution 4:[4]
I'd prefer mapping after making sure the value is available
private String getStringIfObjectIsPresent(Optional<Object> object) {
Object ob = object.orElseThrow(MyCustomException::new);
// do your mapping with ob
String result = your-map-function(ob);
return result;
}
or one liner
private String getStringIfObjectIsPresent(Optional<Object> object) {
return your-map-function(object.orElseThrow(MyCustomException::new));
}
Solution 5:[5]
The example u put is not a good example. Optional shouldn't be sent as parameter into another function. Good practice is always sending non-null parameter into function. So that we know always that the input will not be null. This can decrease our code uncertainty.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Vlad Bochenin |
Solution 3 | marstran |
Solution 4 | iamiddy |
Solution 5 | Ryan Zheng |