有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

lambda调用包含在Java中可选值的列表中?

在Java 8中

我现在有一个lambda,看起来像这样:

.createSomething((acceptableStates, someProxy) -> (userId) ->   
    acceptableStates.contains(someProxy.getSomeAttributeId(userId)))

然而,我们已经改变了一些。getSomeAttributeId以返回Optional<String>而不是字符串

如果返回的属性不是空的,那么基本上检查acceptableStates是否包含someProxy.getSomeAttributeId(userId)的值的最干净/最被接受的方法是什么

(注意:acceptableStates仍然是字符串列表,而不是Optional<String>


共 (4) 个答案

  1. # 1 楼答案

    我强烈建议您编写如下代码片段这样的易懂且清晰的代码:

    Optional<SomeAttributeId> optional = someProxy.getSomeAttributeId(userId);
    
    return optional.isPresent() && acceptableStates.contains(optional.get‌​());
    

    如果someProxy.getSomeAttributeId(userId)为空可选项时不应引发异常(1):

    acceptableStates.contains(someProxy.getSomeAttributeId(userId).orElseThrow(() -> new Exception()))
    

    或者,除非您有默认值(2)来填充结果:

    acceptableStates.contains(someProxy.getSomeAttributeId(userId).orElse(DEFAUT_VALUE))
    

    我的观点是:

    不要追求Java 8的特性,这会把一切都搞砸,尤其是在可以使用简单布尔表达式的情况下。我有过将一些代码重构为普通Java语句的经验,因为项目中的新人(1.1)无法获得代码的功能。随着时间的推移,就连我(作为一名作家)也几乎无法做到这一点(1.2)

    此外,对于那种“lambda chain”样式,一个微小的更改可能会导致完全重写代码片段/方法(2)

    在n-nested lambdas(n>;2 (3).


    无论如何,如果你不同意我的观点,@Eugene提出了一个很好的方法

  2. # 2 楼答案

    return value.isPresent() && value.get().contains("some-text");
    
  3. # 3 楼答案

    不幸的是,我没有看到非常干净的解决方案。参考这个问题:Functional style of Java 8's Optional.ifPresent and if-not-Present?

    此外,如果对getSomeAttributeId的调用确实会占用资源,那么您甚至必须将可选项保存在变量中

    .createSomething((acceptableIds, someProxy) -> (userId) ->
        {
           Optional<String> attrId = someProxy.getSomeAttributeId(userId);
           return attrId.isPresent() ? acceptableStates.contains(attrId.get()) : false;
        })
    
  4. # 4 楼答案

    .... userId -> someProxy.getSomeAttributeId(userId)
                            .map(acceptableStates::contains)
                            .orElse(Boolean.FALSE);