Search code examples
javajava-8optional-chaining

Use Java 8 Optional features in the multiple null conditions


Use Java 8 Optional features in the multiple null conditions

The conditions is

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();
    }

The requirement is to use Java 8 features without checking the null values!!

Need to get the ctryCode??


Solution

  • Just use Optional.map(mapperFunction). If mapperFunction returns null, then .map returns an empty 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);
    

    UPD. You can do it more elegant with taking stream of banks:

    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);
    

    Then you can use mayBeCountryCode, for example, like that:

        mayBeCountryCode.ifPresent(countryCode ->
                // do whatever with a non-null string
        );
    
        String countryCode = mayBeCountryCode.orElse("none");
        String nullableCountryCode = mayBeCountryCode.orElse(null);