【问题标题】:Combining two optionals, cleanest way to write?结合两个选项,最干净的写作方式?
【发布时间】:2020-03-15 02:30:43
【问题描述】:

假设我有:

public void func(){
  Optional<Integer> firstRequiredOptional = ...
  Optional<Integer> secondRequiredOptional = ...

  if(firstRequiredOptional.isPresent() && secondRequiredOptional.isPresent()){
     // do something with values of BOTH optionals
  }

  // Do nothing
}

如果两个选项都存在,这个函数只会执行if

我正在尝试一种更简洁的方式(可能是函数ifPresent 类型)来编写这个,或者以某种方式将其转换为Optional&lt;Integer, Integer&gt;,如果可能的话,两个整数都在一个可选中?

写这个更简洁的方法是什么?

【问题讨论】:

  • @rkosegi:不,这不是这里要问的。
  • @rkosegi 不,它不会。问题不在于链接它们,而是同时使用它们。
  • 为什么觉得不干净?
  • 你的代码对我来说似乎是干净的方式
  • 它完全满足它的需要(不多也不少),速度快,易于阅读。但人们更喜欢复杂的表达方式。

标签: java java-8 optional


【解决方案1】:

使用if 语句已经比其他替代方法更简洁。

备选方案 1

您可以使用ifPresent 如:

firstRequiredOptional.ifPresent(first ->
        secondRequiredOptional.ifPresent(second -> something(first, second)));

备选方案 2

使用allMatchStream 以防您不想使用这些值(不是说不可能),例如:

if (Stream.of(firstRequiredOptional, secondRequiredOptional)
        .allMatch(Optional::isPresent)) {
    something(); // or something(firstRequiredOptional.get(), secondRequiredOptional.get()); 
}

【讨论】:

  • @Olivier 不是。在答案中更新。
【解决方案2】:

取决于你所说的“更清洁”是什么意思。

@Naman 指出,ifPresent 解决方案看起来像:

firstRequiredOptional.ifPresent(firstValue ->
    secondRequiredOptional.ifPresent(secondValue -> {
        // do something with firstValue, secondValue.
    }));

从某种意义上说,这更“干净”,因为您不必在两个选项上同时调用 .isPresent().get()

没有Optional&lt;FirstType, SecondType&gt;,但如果这两个必需值的组合具有某种含义,您可能希望将其体现在一个类中。

Optional<FullName> fullNameOptional = firstNameOptional.flatMap(firstName ->
    secondNameOptional.map(secondName -> new FullName(firstName, secondName));
fullNameOptional.ifPresent(fullName -> {
    // do something with fullName.
});

这具有为您提供可以使用的单个 Optional 值、传递给辅助方法等的优点,并且它遵循命令-查询分离模式,这在调试和将代码分解为时往往具有优势易于单元测试的部分。但它并不是“更干净”,例如,您使用的代码更少。

如果您喜欢映射到单个 Optional 的想法,但又不想为此创建一个类型,您可以创建通用的 Tuple 类(或使用几个流行的 Tuple 库之一)。

【讨论】:

    【解决方案3】:

    可能是两个 Optional 的通用方法:

    import java.util.Optional;
    import java.util.function.BiConsumer;
    
    public class OptionalUtils {
    
        public static <T> void ifPresent(Optional<T> optional1, Optional<T> optional2, BiConsumer<T, T> consumer) {
            if (optional1.isPresent() && optional2.isPresent()) {
                consumer.accept(optional1.get(), optional2.get());
            }
        }
    
        public static void main(String[] args) {
    
            Optional<Integer> test1 = Optional.of(1);
            Optional<Integer> test2 = Optional.of(2);
    
            ifPresent(test1, test2, (a, b) -> {
                System.out.println(" a + b =" + (a + b));
            });
    
        }
    }
    

    【讨论】:

      【解决方案4】:

      不确定是否更干净,但我直观的解决方案是提供一个容器并使用ofNullable

      这可能是这样的:

      public class DualOptional<T, K>
          {
              Optional<T> opt1 = Optional.empty();
              Optional<K> opt2 = Optional.empty();
      
              DualOptional( T t, K k )
              {
                  opt1 = Optional.ofNullable( t );
                  opt2 = Optional.ofNullable( k );
              }
      
              public boolean isPresent()
              {
                  return opt1.isPresent() && opt2.isPresent();
              }
          }
      

      这当然可以扩展到包括 getter 和任何其他需要的功能。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-04
        • 1970-01-01
        • 2021-03-20
        • 2010-09-18
        • 2021-06-25
        相关资源
        最近更新 更多