代码优化之switch语句和数组的妙用
一、基本知识复盘1.数组(1) 什么是数组用来存储固定长度、相同类型数据的容器(2) 定义方式① 声明 分配空间常用int[] arr new int[5];② 声明 直接赋值int[] arr {10, 20, 30, 40}; String[] names {张三, 李四, 王五};③ 先声明后赋值int[] arr; arr new int[]{1,2,3};(3) 遍历① 普通 for 循环for (int i 0; i arr.length; i) { System.out.println(arr[i]); }② 增强 for 循环for (int num : arr) { System.out.println(num); }2.switch(1) switch语句是多分支选择语句适合固定等值判断相比多层if-else if代码更简洁(2) 基本语法switch(表达式) { case 常量1: 代码块1; break; case 常量2: 代码块2; break; // 多个case default: 默认代码块; break; }default说明可选不是必须写位置任意不一定在最后所有 case 都不匹配才会执行建议最后也加上break避免穿透(3) 支持的类型基础类型JDK 1.0byte、short、int、char包装类JDK 5 自动装箱Byte、Short、Integer、Character字符串JDK 7 新增String枚举JDK 5 新增enum枚举类型注switch不支持long、float、double、boolean(4) 使用场景优先用 switch等值判断、分支多、固定常量优先用 if范围判断、、区间、复杂逻辑判断(5) JDK14 新特性增强 switch箭头语法、表达式箭头 case无穿透不用写 breakint num 2; switch (num) { case 1 - System.out.println(一); case 2 - System.out.println(二); default - System.out.println(其他); }switch 作为表达式直接返回值int num 3; String res switch (num) { case 1 - 第一名; case 2 - 第二名; default - 其他名次; }; System.out.println(res);二、代码优化方案1.核心思想数组统一管理映射关系、常量、批量数据消除魔法值、重复变量集中配置便于维护。switch替代多层if-else if做等值分支判断语法结构清晰、可读性高、执行效率优于长串 if。组合使用数组存静态文案 / 配置 / 参数switch 处理分支业务逻辑各司其职。2.优化场景(1) 数字编码 ↔ 文本描述最常用消除魔法值此时业务中大量存在状态码、类型码、错误码对应中文 / 提示语。反例硬编码 多层 if维护极差public static String getStatusName(int status) { if (status 1) { return 待审核; } else if (status 2) { return 审核通过; } else if (status 3) { return 审核驳回; } else if (status 4) { return 已作废; } return 未知状态; }问题新增状态要改 if 分支、文本分散、重复代码多。优化方案数组做映射纯映射无需 switch// 数组下标 状态码值 对应文本集中配置 private static final String[] STATUS_MAPPING { 未知状态, // 0 待审核, // 1 审核通过, // 2 审核驳回, // 3 已作废 // 4 }; public static String getStatusName(int status) { // 边界校验防止数组越界 if (status 0 || status STATUS_MAPPING.length) { return STATUS_MAPPING[0]; } return STATUS_MAPPING[status]; }优势配置统一修改文案只改数组时间复杂度 O (1)性能最优新增状态仅扩展数组长度。(2) 等值分支逻辑if-else 臃肿 → switch 优化当不同编码不仅要返回文本还要执行不同业务逻辑搭配switch拆分分支数组承载文案配置。反例多层 if逻辑混杂public static void handleOrder(int orderStatus) { if (orderStatus 1) { System.out.println(待付款提醒用户支付); // 业务逻辑A } else if (orderStatus 2) { System.out.println(已付款通知仓库发货); // 业务逻辑B } else if (orderStatus 3) { System.out.println(已发货更新物流信息); // 业务逻辑C } else if (orderStatus 4) { System.out.println(已完成生成结算单); // 业务逻辑D } else { System.out.println(未知订单状态); } }优化方案数组存文案 switch 处理分支逻辑public class OrderService { // 常量数组统一管理状态文本全局静态常量规范写法 private static final String[] ORDER_STATUS { 未知订单状态, 待付款, 已付款, 已发货, 已完成 }; public static void handleOrder(int orderStatus) { switch (orderStatus) { case 1: System.out.println(ORDER_STATUS[1] 提醒用户支付); // 专属业务逻辑 break; case 2: System.out.println(ORDER_STATUS[2] 通知仓库发货); // 专属业务逻辑 break; case 3: System.out.println(ORDER_STATUS[3] 更新物流信息); // 专属业务逻辑 break; case 4: System.out.println(ORDER_STATUS[4] 生成结算单); // 专属业务逻辑 break; default: System.out.println(ORDER_STATUS[0]); } } }进阶利用 switch 穿透合并相同逻辑多个编码执行同一套逻辑省略break实现分支合并搭配数组复用文案// 需求1/2/3 都属于正常订单4/5 属于异常订单 public static void checkOrder(int code) { String[] tip {未知, 正常订单, 异常订单}; switch (code) { case 1: case 2: case 3: System.out.println(tip[1] 正常流转); break; case 4: case 5: System.out.println(tip[2] 触发告警); break; default: System.out.println(tip[0]); } }(3) 非连续编码 / 复杂参数映射数组 switch 组合实际开发中状态码不连续如 101、202、305无法直接用数组下标映射此时数组存放通用配置 / 固定参数switch 精准匹配离散编码。// 数组统一配置通用提示语 private static final String[] MSG {操作失败, 操作成功, 权限不足}; public static void operate(int code) { switch (code) { case 101: System.out.println(MSG[1] 新增数据); break; case 202: System.out.println(MSG[1] 修改数据); break; case 305: System.out.println(MSG[2] 禁止操作); break; default: System.out.println(MSG[0]); } }(4) 批量数据处理纯数组优化搭配循环针对重复变量、批量计算、批量操作用数组替代零散变量结合循环简化代码常和分支判断联动。反例零散变量冗余严重int s1 88; int s2 92; int s3 79; int total s1 s2 s3; double avg total / 3.0;优化数组 循环public static void calcScore() { // 数组统一存储批量数据 int[] scores {88, 92, 79}; int total 0; for (int score : scores) { total score; } double avg (double) total / scores.length; System.out.println(总分 total 平均分 avg); }结合 switch 做分组统计综合实战// 按分数段分类统计 public static void scoreGroup(int[] scores) { int excellent 0, good 0, pass 0; for (int s : scores) { int level; if (s 90) level 1; else if (s 60) level 2; else level 3; switch (level) { case 1: excellent; break; case 2: good; break; case 3: pass; break; } } String[] label {优秀, 良好, 不及格}; System.out.println(label[0] : excellent); System.out.println(label[1] : good); System.out.println(label[2] : pass); }3. 编码规范 避坑要点(1)数组使用规范状态映射数组定义为private static final全局常量避免重复创建必须做下标越界校验index 0 index 数组名.length防止ArrayIndexOutOfBoundsException编码连续优先数组编码离散优先 switch 数组组合。(2)switch 使用规范只用于等值判断范围判断、、区间仍用 if非特殊场景禁止省略 break避免意外穿透建议保留default分支兜底异常值case 后只能是常量不能使用变量、表达式。(3)组合使用取舍仅做编码→文本映射只用数组最简单高效编码匹配 多分支业务逻辑数组存文案switch 走逻辑分支少于 3 个直接用 if 即可没必要强行用 switch。(4)性能对比数组下标访问O (1)性能最高switch底层查表性能优于 3 层以上的 if-else if 链分支极多场景数组 switch 多层 if。三、实践1.第一段代码/** * 实现对应消息类型是否已经校验通过常用来对业务流程是否合法进行校验 * */ private boolean verify(RequestInfo request, MapString, Item items) { if(request.getAut().equals(02) || request.getAut().equals(03)) { Item item02 items.get(theMsgOf02); if(ObjectUtil.isEmpty(item02)){ return false; } String status item02.get(status); return PASS.equals(status) ?true:false; } if(request.getAut().equals(05) ) { Item item05 items.get(theMsgOf05); if(ObjectUtil.isEmpty(item05)){ return false; } String status item05.get(status); return PASS.equals(status) ?true:false; } return true; }使用switch语句(Java7及以上版本)进行了优化减少了重复代码并提高了可读性private boolean verify(RequestInfo request, MapString, Item items) { String auth request.getAut(); Item itemInfo; String verifyStatusKey; switch (auth){ case 02: case 03 verifyStatusKey theMsgOf02; break; case 05 verifyStatusKey theMsgOf05; break; default: return ture; } itemInfo items.get(verifyStatusKey); if(ObjectUtil.isEmpty(item02)){ return false; } String status itemInfo.get(status); return PASS.equals(status); }2.第2段代码private boolean verify(String wltType, MapString, Item items){ Item item1 items.get(msgType1); if(ObjectUtil.isEmpty(item1)){ return false; } String status1 item1.getStatus(); Item item2 items.get(msgType2); if(ObjectUtil.isEmpty(item2)){ return false; } String status2 item2.getStatus(); return PASS.equals(status1) PASS.equals(status2); }通过简化条件判断和消息重复代后的代码private boolean verify(String wltType, MapString, Item items){ // 定义所有格需要验证的状态码 String[] verifyKeys {msgType1, msgType2}; for(String key : verifyKeys) { Item item items.get(key); if(ObjectUrtil.isEmpty(item) || !PASS.equals(item.getStatus())) { return false; } } return true; }3.第3段代码String verifyKeys; switch(wltLevel) { case LEVEL1: String[] passGroup1 new String[]{msgType.01.01, msgType.02.02}; String[] passGroup2 new String[]{msgType.05.01, msgType.06.00}; String[] passGroup3 new String[]{msgType.11.01, msgType.12.01}; String[] passGroup4 new String[]{msgType.01.37, msgType.56.02}; break; default: String[] passGroup5 new String[]{msgType.01.01, msgType.02.02, msgType.06.02}; String[] passGroup6 new String[]{msgType.07.01, msgType.09.02, msgType.32.02}; } // Problem:其中任意一组每个msgType类型校验通过则说明对应的Level校验通过 应该怎么实现实现任一数组校验通过即为true的需求可以将每组验证键存储在一个二维数组中然后遍历这个数组检查每组是否都存在于items中且验证状态符合要求private boolean verifyGroup(String wltLevel, MapString, Item items){ String[][] verifyKeysMatrix; String verifyKeys; switch(wltLevel) { case LEVEL1: String[] passGroup1 new String[]{msgType.01.01, msgType.02.02}; String[] passGroup2 new String[]{msgType.05.01, msgType.06.00}; String[] passGroup3 new String[]{msgType.11.01, msgType.12.01}; String[] passGroup4 new String[]{msgType.01.37, msgType.56.02}; break; default: String[] passGroup5 new String[]{msgType.01.01, msgType.02.02, msgType.06.02}; String[] passGroup6 new String[]{msgType.07.01, msgType.09.02, msgType.32.02}; } for(String[] verifyKeys : verifyKeysMatrix){ boolean groupValid true; for(String key : verifyKeys) { Item item items.get(key); if(item null || !PASS.equals(item.getStatus())){ // 如果当前组内任一验证失败则跳出循环检查下一组 groupValid false; break; } } // 任意一组验证通过即返回true if(groupValid){ return true; } } return false; }