Lambda 将复杂逻辑转换为流/可选

Lambda 将复杂逻辑转换为流/可选,lambda,java-8,java-stream,Lambda,Java 8,Java Stream,我正在尝试将下面的代码(很多if/for/null检查)转换为stream/optional。已经尝试了一段时间,但无法使其正确。任何帮助都将不胜感激!谢谢 String id = null; String res = null; List<ShoppingCandidate> shoppingCandidates = null; List<DiscoveredIdentity> discoveredIdentityList = null;

我正在尝试将下面的代码(很多if/for/null检查)转换为stream/optional。已经尝试了一段时间,但无法使其正确。任何帮助都将不胜感激!谢谢

    String id = null;
    String res = null;
    List<ShoppingCandidate> shoppingCandidates = null;
    List<DiscoveredIdentity> discoveredIdentityList = null;
    Optional<DiscoveredIdentities> discoveredIdentities = contextAccessor.maybeAccess(DiscoveredIdentities.class);
    Optional<DiscoveredShoppingCandidates> discoveredShoppingCandidates = contextAccessor.maybeAccess(DiscoveredShoppingCandidates.class);
    
    if(discoveredShoppingCandidates.isPresent()){
        shoppingCandidates = discoveredShoppingCandidates.get().getShoppingCandidates();
    }
    if(shoppingCandidates != null){
        for(ShoppingCandidate shoppingCandidate : shoppingCandidates){
            if(shoppingCandidate.getIdentityReferenceList() != null){
                for(IdentityReference identityReference : shoppingCandidate.getIdentityReferenceList()){
                    if(identityReference.getIdRole().equals("123")){
                        id = identityReference.getReferenceId();
                    }
                }
            }
        }

    }
    
    if(discoveredIdentities.isPresent()){
        discoveredIdentityList = discoveredIdentities.get().getDiscoveredIdentityList();
        if(discoveredIdentityList != null){
            for(DiscoveredIdentity discoveredIdentity : discoveredIdentityList){
                if(discoveredIdentity.getIdentityId().equals(id)){
                    List<IdentityKey> identityKeyList = discoveredIdentity.getIdentityKeyList();
                    if(identityKeyList != null){
                        for(IdentityKey key: identityKeyList){
                            if(key.getIdType().equals("CID")){
                                res = key.getId();
                            }
                        }
                    }
                }
            }                
        }
    }
String id=null;
字符串res=null;
列出购物候选项=空;
List discoveredIdentityList=null;
可选的discoveredidenties=contextAccessor.maybeAccess(discoveredidenties.class);
可选discoveredShoppingCandidates=contextAccessor.maybeAccess(discoveredShoppingCandidates.class);
if(discoveredShoppingCandidates.isPresent()){
shoppingCandidates=discoveredShoppingCandidates.get().getShoppingCandidates();
}
if(购物候选!=null){
for(ShoppingCandidate ShoppingCandidate:shoppingCandidates){
if(shoppingCandidate.getIdentityReferenceList()!=null){
for(IdentityReference IdentityReference:shoppingCandidate.getIdentityReferenceList()){
if(identityReference.getIdRole().equals(“123”)){
id=identityReference.getReferenceId();
}
}
}
}
}
if(discoveredIdentity.isPresent()){
discoveredIdentityList=discoveredIdentities.get().getDiscoveredIdentityList();
if(discoveredIdentityList!=null){
for(发现身份发现身份:发现身份列表){
if(discoveredIdentity.getIdentityId().equals(id)){
List identityKeyList=discoveredIdentity.getIdentityKeyList();
if(identityKeyList!=null){
用于(标识键:标识键列表){
if(key.getIdType().equals(“CID”)){
res=key.getId();
}
}
}
}
}                
}
}

您的代码是不安全的,因为您的
id
可能最终为
null
,并且基于它的后续检查将无效

另外,使用
Optional::isPresent
只是过程
if-else
的伪装。你能找到区别吗

if (something != null) {
   // use something
}
没有区别。
可选
的功能在于使用链接方法,如
映射
平面映射
过滤器
或ELSE

如果您试图根据
Optional
的正确用法,将每个代码的
If-else过程“转换”为某些内容,则可能会产生如下结果。它仍然非常笨拙,老实说,尽管使用了正确的方法,但差别并没有显现出来。由于结构和逻辑的复杂性,维修性仍然受到质疑

在我看来,
可选
在这种情况下无法帮助您实现可维护性和清晰性。您获得的唯一优势是处理未找到
id
的情况(即
null

我建议您将逻辑片段提取到单独的方法中,以实现干净的代码

最后,看一看(未经测试,但它给了您一个想法):


你试过什么吗?
if (optionalSomething.isPresent()) {
   // use optionalSomething.get();
}
String res = discoveredShoppingCandidates
       .map(DiscoveredShoppingCandidates::getShoppingCandidates)
       .orElse(Collections.emptyList())
       .stream()
       .map(ShoppingCandidate::getIdentityReferenceList)
       .filter(Objects::nonNull)
       .flatMap(Arrays::stream)
       .filter(s -> "123".equals(s.getIdRole()))
       .map(IdentityReference::getReferenceId)
       .flatMap(id -> discoveredIdentities
               .map(DiscoveredIdentities::getDiscoveredIdentityList)
               .orElse(Collections.emptyList())
               .stream()
               .filter(s -> Objects.equals(id, s.getIdentityId()))
               .flatMap(s -> s.getIdentityKeyList().stream())
               .filter(Objects::nonNull)
               .filter(s -> "CID".equals(s.getIdType()))
               .map(IdentityKey::getId))
       .findFirst()
       .orElse(null);