嵌套Optional.map的优美替代方案?

时间:2019-09-09 23:13:10

标签: java optional

我有多个Optional必须映射到POJO。有没有比以下更好的选择了?

class SimplePojo {
    private String stringField;
    private Integer integerField;
    // All args. constructor, getter, setter
}

Optional<String> stringOptional = ...
Optional<Integer> integerOptional = ...
Optional<SimplePojo> simplePojoOptional = stringOptional.flatMap(
    string -> integerOptional.map(integer -> new SimplePojo(string, integer)))

在上面的示例中,为了简化起见,我将问题简化为2个Optional。但是我实际上有3个Optionals,还有更多选择。恐怕最后一行很快就会变得很笨拙。

请注意:不能使用Vavr或Functional Java之类的功能框架。

2 个答案:

答案 0 :(得分:1)

如何使用Builder

class SimplePojo {

  public static class Builder {
    private String stringField;

    public Builder withStringField(String str) {
      this.stringField = str;
      return this;
    }
    // and other "with" methods...


    public Optional<SimplePojo> build() {
      if (stringField == null || anotherField == null /* and so forth */) {
        return Optional.empty();
      } else {
        return Optional.of(new SimplePojo(this));
      }
    }
  }
  private final String stringField;

  /* private constructor, so client code has to go through the Builder */
  private SimplePojo(Builder builder) {
    this.stringField = builder.stringField;
    // etc.
  }
}

然后您可以按以下方式使用它:

SimplePojo.Builder builder = new SimplePojo.builder();
optionalStringField.ifPresent(builder::withStringField);
// etc.
return builder.build();

答案 1 :(得分:1)

在这种方式下追求功能风格没有任何优势。查看三个选项:

ONE::如果可以更改SimplePojo类,并且这种情况很常见,则可以考虑向SimplePojo添加工厂方法:

class SimplePojo {
  public static Optional<SimplePojo> of(final Optional<String> stringField, final Optional<Integer> integerField) {
    if (stringField.isPresent() && integerField.isPresent()) {
      return new SimplePojo(stringField.get(), integerField.get());
    else
      return Optional.empty();
  }
}

两个:如果无法更改SimplePojo,则可能要在其他地方将其创建为实用程序方法。如果只在一个类中需要这种模式,请在该类中将方法设为私有!

三:如果您只需要执行一次或两次,那么我宁愿从第一个选项开始使用if...then构造,而不是为了便于阅读而使用的功能符号:< / p>

final Optional<SimplePojo> simplePojoOptional;
if (stringField.isPresent() && integerField.isPresent()) {
  simplePojoOptional = new SimplePojo(stringField.get(), integerField.get());
else
  simplePojoOptional = Optional.empty();
相关问题