首页 > 解决方案 > 如何在流 API 中正确使用 .map 和 .orElseGet 的组合?

问题描述

我有以下代码:

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(...));
}

它不会编译并说:
“lambda 表达式中的返回类型错误:List<User>无法转换为Optional<List<User>>
,即使 findXYZ 和所有其他 if/else 语句实际上返回了 List 类型。

有人可以向我解释代码有什么问题吗?

编辑:对不起,我注意到其中一个 if 语句实际上是返回 List 的 Optional

如果有人感兴趣,我只需将第一个“if”编辑为:

return userService.getUsersFromAnotherObject(anotherObject.orElse(null));

标签: lambdajava-8java-streamoptionalfindfirst

解决方案


(已编辑)

在您的情况下,两者的返回应该匹配,因为这是使用orElseGet()- 来提供相同类型的替代值。

.map(code -> return ...)
.orElseGet(() -> return ...)

您的情况有两种选择:

  1. 由于您的 map() 返回Optional<List<User>>,您可以更新findXyz()以返回相同的

  2. 将代码更新为map()如下所示(List<User>不带Optional包装返回,然后您可以保留findXyz()原始代码)。

         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(...));`
    

推荐阅读