I have the following code:
private List<User> findUsers(...) {
...
return usersData.stream() //userData is another list of objects
.findFirst()
.map(this::getCode)
.map(code-> {
if (...) {
Optional<AnotherObject> anotherObject = getAnotherObject();
return anotherObject.map(userService::getUsersFromAnotherObject) // getUsersFromAnotherObject returns List<User> but the whole line returns Optional of List<User>
} else {
...
return null;
}
}).orElseGet(() -> findXYZ(...));
}
which does not compile and says:
"Bad return type in lambda expression: List<User>
cannot be converted to Optional<List<User>>
"
even though findXYZ and all other if/else statements return in fact type List.
Could anybody explain to me what is wrong with the code?
EDIT: Sorry, I noticed that one of if statements is actually returning the Optional of List
If anybody is interested, I solved it simply editing the first "if" to:
return userService.getUsersFromAnotherObject(anotherObject.orElse(null));
(edited)
In your case, the return of the two should match because that's the use of the orElseGet()
- to give an alternate value of the same type.
.map(code -> return ...)
.orElseGet(() -> return ...)
There are two options in your case:
since your map() returns Optional<List<User>>
, you can update the findXyz()
to return the same
update code of map()
to something like below (return List<User>
without Optional
wrap, then you can keep your findXyz()
in it's original).
usersData.stream().findFirst()
.map(this::getCode)
.map(code-> {
if (...) {
Optional<AnotherObject> anotherObject = getAnotherObject();
Optional<List<User>> optUserList = anotherObject.map(userService::getUsersFromAnotherObject)
return optUserList.isPresent() ? optUserList.get() : null;
} else {
...
return null;
}
}).orElseGet(() -> findXYZ(...));`