多层for嵌套循环遍历,如何跳出当前循环继续下一个循环?

很多做了多年java开发的同学也不一定搞懂,如何在多个for嵌套循环中,判断某个条件满足时,直接结束当前循环,跳出到外层或者某一层继续下个循环,今天我带领大家来了解下多层嵌套循环,如何结束当前循环继续到指定层级继续循环

题目:
假设有3个列表ABC需要嵌套循环遍历,ABC的关系是,A包含B,B包含C,也就是说,A是父,B是A的子集,C是B的子集。现在先遍历A,然后从A中取出B列表,继续遍历B,然后又从B中取出C,继续遍历C。现在想在B遍历C时,有个业务处理,满足条件的,就跳出循环到下一个A继续遍历,如何实现?

其实,类似于这个题目的实际使用场景也是很多的,在实际开发过程中,也会经常遇到的,比如一个组织中,取出部门进行查询部门下某一个用户是否满足一定条件,如果满足,则记录下该用户。实现方式也有很多很多种,我先按照一般的逻辑来写个代码,代码只是解决问题的思路,而不是就拿部门和用户的关系来实现,思路仅供参考

        int a=100;
        int b=300;
        int c=1000;
        for (int x=0;x<a;x++){
    
    
            //标识,如果满足条件的,就回调第一层级继续循环
            boolean flag=false;
            for (int y=0;y<b;y++){
    
    
                for (int z=0;z<c;z++){
    
    
                    //业务处理逻辑,满足条件,跳出循环到第一层
                    if(c>b+100){
    
    
                    //TODO 处理业务逻辑
                        flag=true;
                        break;
                    }
                }
                if(flag){
    
    
                    //已经满足条件,自动跳出循环,继续下一个循环
                    break;
                }
            }
            
        }

这个代码是不是很挫?
虽然也能达到一样的效果,但是业务复杂度也增加了一些,至少多了一个标识要去维护,对于代码的阅读性也变差了,是否有其他更好的方法?

贴代码:

        int a=100;
        int b=300;
        int c=1000;
        harry:for (int x=0;x<a;x++){
    
    
            for (int y=0;y<b;y++){
    
    
                for (int z=0;z<c;z++){
    
    
                    //业务处理逻辑,满足条件,跳出循环到第一层
                    if(c>b+100){
    
    
                        //TODO 处理业务逻辑
                        //跳出循环到harry继续下个循环
                        continue harry;
                    }
                }
            }

        }

这样的代码是不是减少了一些?阅读性也好了很多

  • 首先在需要结束继续的for循环前定义了一个标识,标识名称可以任意取,如harry
  • 循环遍历子集,无论是多少层级的循环,当满足业务逻辑需要跳出循环到指定层级时,只需要 continue 标识名;如:continue harry; 就可以了

然后我们来处理上述题目,怎么写代码:

harry:for( A){
    
    
  for(B){
    
    
		for(C){
    
    
			if(xxx){
    
    
			//处理业务
			continue harry;
			}
		}
	}
}

大概就这样搞定了

顺便介绍下我项目中是怎么使用的吧

我在某上市公司做第三方接口集成时,需要回调第三方接口,修改流程的状态。这个回调第三方接口本来是已经有同事实现过了的,同事的实现代码偶尔很高,我大概说一下我同事是怎么做的

  • 首先在spring boot 配置文件中配置了第三方接口URL地址
  • 在代码中读取到配置文件URL地址,然后再根据流程编码前缀是否满足条件发起第三方接口回调修改状态

其实这样做是没有什么问题的,但是很死板,如果要集成第二个第三方回调,那就必须要改代码了

现在让我来做,我怎么做呢?

  • 首先将流程编码前缀和第三方URL定义在配置文件中,这是一个对象,流程编码允许多个,逗号隔开,流程编码和URL是在一个对象中,多个第三方,就是一个list,配置如下:
thirdparty:
  updatestatus:
    callbacks:
      - serverUrl: https://xxx/api/workflow/callback     #第三方回调修改状态的URL
        workflowCodePrefixs: xxx       #回调流程模板前缀,为空是所有流程都回调修改状态,不为空,则只过滤符合条件的流程修改状态,多个用逗号隔开
        activityCodePrefixs: xxx       #指定节点回调,不为空,则只过滤符合条件的流程修改状态,多个用逗号隔开
        appId: xxx       #APPID
        appSecret:  xxx
  • 读取配置映射到对象的list上
@Data
@Configuration
@ConfigurationProperties(prefix = "thirdparty.updatestatus")
public class UpdateStatusCallBackConfig {
    
    
    //第三方流程回调修改状态配置信息
    private List<CallBackServer>callbacks;
}
  • 再根据配置信息判断满足条件的执行调用第三方修改状态
public String updateStatus(String workflowCode,String activityCode,String workflowInstanceId,String status){
    
    
        List<CallBackServer> callbacks = updateStatusCallBackConfig.getCallbacks();
        if(CollectionUtils.isEmpty(callbacks)){
    
    
            return null;
        }
        StringBuilder result=new StringBuilder();
        harry:for (CallBackServer callBackServer:callbacks){
    
    
            if(StringUtils.isNotEmpty(activityCode)){
    
    
          
                String activityCodePrefixs = callBackServer.getActivityCodePrefixs();
                if(StringUtils.isNotEmpty(activityCodePrefixs)){
    
    
                    String[] activityCodePrefixStrs = activityCodePrefixs.split(",");
                    for (String activityCodePrefix:activityCodePrefixStrs){
    
    
                        if(activityCode.startsWith(activityCodePrefix)){
    
    
                              //调用第三方回调
                            continue harry;
                        }
                    }
                }
            }
            //根据流程编码回调
            String workflowCodePrefixs = callBackServer.getWorkflowCodePrefixs();
            if(StringUtils.isNotEmpty(workflowCodePrefixs)){
    
    
                String[] workflowCodePrefixStrs = workflowCodePrefixs.split(",");
                for (String workflowCodePrefix:workflowCodePrefixStrs){
    
    
                    if(workflowCode.startsWith(workflowCodePrefix)){
    
    
                          //调用第三方回调
                        //跳出本次循环,继续其他第三方配置回调
                        continue harry;
                    }
                }
            }else {
    
    
                //默认都回调
               //调用第三方回调
            }
        }

        return result.toString();
    }

我这个案例中,首先循环遍历配置的第三方接口配置信息,然后在根据流程编码或者节点编码转为数组,如果有多个的话,去遍历数组里面的元素,满足条件的 话,就调用第三方接口修改流程状态,并且跳出本次循环,继续下一个循环

可能我项目中的案例不容易看懂,这个没有关系,毕竟这是业务中的,需要了解业务需求才好去理解,我这里要说的是,多层for嵌套循环的使用场景供大家学习

猜你喜欢

转载自blog.csdn.net/huangxuanheng/article/details/119135084