使用Java8的Optional <T>以功能方式更新源的默认值

her*_*man 3 java functional-programming java-8

这可能是关于函数式编程的问题而不是Java 8的问题,但它正是我现在正在使用的.

我有一个源对象(可能代表一个存储库,或者一个会话......,这里没关系),它有一个retrieveSomething()返回的方法Optional<SomethingA>.我有一个方法返回一个Something,通过调用retrieveSomething()并提供一个默认值,以防可选项为空,如下所示:

return source.retrieveSomething()
             .orElseGet(() -> provideDefaultValue());
Run Code Online (Sandbox Code Playgroud)

现在我想修改此代码,以便在源不包含任何值的情况下(因此可选项为空),源将使用提供的默认值进行更新.

当然,我可以在lambda表达式代码块中轻松完成:

return source.retrieveSomething()
             .orElseGet(() -> {
                     Something sth = provideDefaultValue()
                     source.putSomething(sth);
                     return sth;
                 });
Run Code Online (Sandbox Code Playgroud)

但如果我理解正确,我不应该使用导致副作用的功能.那么做到这一点的"正确"(功能)方法是什么,保持使用的好处Optional(在实际代码中我实际上也在map对它执行操作,但这在这里无关紧要)?

dka*_*zel 5

您可以按照Java使用Map.computeIfAbsent()的方式进行操作

它接受第二个参数,它是如何计算和插入记录的函数:

所以你的代码将成为:

Something something = source.computeIfAbsent(sth, (k)->provideDefaultValue());
Run Code Online (Sandbox Code Playgroud)

使用lambda来计算默认值而不是仅仅传入它的优点是,只有在需要时才计算lambda,如果计算默认值很昂贵,则只需在需要时付费即可.