在多个 null 条件中使用 Java 8 可选功能

Kis*_*ore 0 java java-8 optional-chaining

在多个 null 条件中使用Java 8 可选功能

条件是

Optional<Payee> payee = Optional.ofNullable(paymtTrans.getPayee());
    
    if (payee.isPresent()
            && payee.get().getPayeeAcc() != null
            && payee.get().getPayeeAcc().size() > 0
            && payee.get().getPayeeAcc().get(0).getBnk() != null
            && payee.get().getPayeeAcc().get(0).getBnk().getBnkCtryCode() != null) {
        String ctryCode = payee.get().getPayeeAcc().get(0).getBnk().getBnkCtryCode();
    }
Run Code Online (Sandbox Code Playgroud)

要求是使用 Java 8 功能而不检查空值!!

需要获取ctryCode吗?

G.D*_*rov 7

只需使用Optional.map(mapperFunction). 如果mapperFunction返回 null,则.map返回一个空的Optional:

Optional<Payee> payee = Optional.ofNullable(paymentTransaction.getPayee());
Optional<String> mayBeCountryCode = 
    payee
        .map(Payee::getPayeeAccounts)
        .filter(banks -> banks.size() > 0)
        .map(banks -> banks.get(0))
        .map(BankHolder::getBank)
        .map(Bank::getBankCountryCode);
Run Code Online (Sandbox Code Playgroud)

UPD。 您可以通过银行流来做到更优雅:

Optional<Payee> payee = Optional.ofNullable(paymentTransaction.getPayee());
Optional<String> mayBeCountryCode = 
    payee
        .map(Payee::getPayeeAccounts)
        .map(Collection::stream)
        .flatMap(Stream::findFirst)
        .map(BankHolder::getBank)
        .map(Bank::getBankCountryCode);
Run Code Online (Sandbox Code Playgroud)

然后你可以使用mayBeCountryCode,例如,像这样:

    mayBeCountryCode.ifPresent(countryCode ->
            // do whatever with a non-null string
    );

    String countryCode = mayBeCountryCode.orElse("none");
    String nullableCountryCode = mayBeCountryCode.orElse(null);
Run Code Online (Sandbox Code Playgroud)

  • 根据您的代码, getPayeeAccounts() 是 `Payee` 类的一个方法,在此处调用:`.map(Payee::getPayeeAccounts)` (2认同)
  • 优秀的答案,聪明。我想补充一点,如果程序员想要返回一个具有特殊信号值(如“none”)的字符串,而不是返回“Optional&lt;String&gt;”,他们可以再添加一个调用 ([`Optional.orElse`](https ://docs.oracle.com/en/java/javase/20/docs/api/java.base/java/util/Optional.html#orElse(T))) 到链: `.orElse( "none" )` (2认同)
  • 我会将 `banks-&gt;banks.size() &gt; 0` 更改为 `banks-&gt;!banks.isEmpty()` ,恕我直言,它更多地描述了您正在检查的内容。 (2认同)
  • 如何获取 getPayeeAccounts() 并仅选择第一个帐户?– Ans - 使用 findFirst() 方法 payee.map(Payee::getPayeeAccounts).findFirst(); @Kishore_2021 (2认同)
  • 也感谢@java_coder (2认同)