【问题标题】:Problem while converting old-school if usage to Optional.ifPresent()将老式 if 使用转换为 Optional.ifPresent() 时出现问题
【发布时间】:2018-09-30 22:51:59
【问题描述】:

在将老式 if 用法转换为 Optional.ifPresent 时遇到问题。这是以前版本的代码。

State state = State.OK;
final Optional<Person> checkExistingPerson = checkIt();

if(checkExistingPerson.isPresent()) {
    Person person = checkExistingPerson.get();

    if("blah".equals(person.getName())) {
        state = State.DUPLICATE;
    } else {
        state = State.RESTORED;
    }

    return Member(person.getId(), state);
}

return Member(null, state);

这是Optional.ifPresent的用法

State state = State.OK;
final Optional<Person> checkExistingPerson = checkIt();

checkExistingPerson.ifPresent(person -> {

    if("blah".equals(person.getName())) {
        state = State.DUPLICATE;
    } else {
        state = State.NEW;
    }

    return Member(person.getId(), state);
});

return Member(null, state);

此外,这是 IntelliJ 强制我更改的屏幕截图。

对于我的问题,使用Optional 的最佳方法是什么?谢谢大家!

【问题讨论】:

    标签: java lambda java-8 optional


    【解决方案1】:
    1. lambda 中的外部变量必须是 final
    2. ifPresent 接受 Consumer 所以它没有返回值,因此你不能使用 return Member(person.getId(), state); (还要记住你在一个 lambda 中,所以 return 不会退出你的方法,而是从λ)。

    map 改为接受具有返回值的 Function,因此您可以使用它来代替 ifPresent

    这就是重构代码的方法,将state 移动到 lambda 中并使用maporElseGet

    return checkExistingPerson.map(person -> {
        State state;
    
        if("blah".equals(person.getName())) {
            state = State.DUPLICATE;
        } else {
            state = State.NEW;
        }
    
        return Member(person.getId(), state);
    })
    .orElseGet(() -> Member(null, State.OK));
    

    【讨论】:

      【解决方案2】:

      您不能在 lambda 表达式中更改局部变量的值。另外ifPresent不能返回值,因为它的返回类型是void

      相反,您应该使用Optional.map,它会转换由Optional 包裹的对象(如果存在):

      return checkExistingPerson
          .map(person -> new Member(
                  person.getId(), 
                  "blah".equals(person.getName()) ? State.DUPLICATE : State.RESTORED))
          .orElse(new Member(null, State.OK));
      

      【讨论】:

        【解决方案3】:

        在内部方法中,如果外部变量未定义为 final,则不能引用它们,您可以像这样更改方法:

        final Optional<Person> checkExistingPerson = checkIt();
        
        checkExistingPerson.ifPresent(person -> {
            State state;
            if("blah".equals(person.getName())) {
                state = State.DUPLICATE;
            } else {
                state = State.NEW;
            }
        
            return Member(person.getId(), state);
        });
        
        return Member(null, State.OK); 
        

        【讨论】:

        • 感谢您的回答。现在,对于内部回报,它说Unexpected return value。这是什么原因?
        • 这不会编译
        【解决方案4】:

        如果您在 lambda 表达式中访问局部变量,那么变量应该是 final 或有效 final,这意味着它们不能被修改 here,您也可以在 lambda 表达式中声明变量。以及关于问题 ifPresent 的主题将Consumer 作为没有返回类型的参数,您使用map 将采用Function 和@Loris 的参数

        【讨论】:

        • 这不会编译
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-24
        相关资源
        最近更新 更多