如何简化Java类中基于计数器设置同值字段的switch-case逻辑?
优化方案
1. 重构数据结构(推荐)
最彻底的解决方式是把分散的user_Id_1、user_Id_2这类重复字段替换为集合类型,比如List<String>,直接通过索引操作消除分支判断:
import java.util.ArrayList; import java.util.Collections; import java.util.List; public class User { // 用列表替代多个独立字段,索引0对应原num=1,以此类推 private List<String> userIds = new ArrayList<>(Collections.nCopies(4, null)); public void setUserId(int num, String userId) { // 先校验序号合法性,避免索引越界 if (num >= 1 && num <= userIds.size()) { userIds.set(num - 1, userId); } else { throw new IllegalArgumentException("无效的序号:" + num); } } // 如需兼容原有业务的单独字段获取,可保留对应getter public String getUser_Id_1() { return userIds.get(0); } public String getUser_Id_2() { return userIds.get(1); } // 其他getter同理... }
后续新增序号时,只需调整列表初始化的大小,无需修改setUserId方法,代码扩展性极强。
2. 预存Setter映射(Java 8+)
如果不能修改原有字段结构,可借助Java 8的函数式接口,提前建立序号与setter方法的映射,消除冗余分支:
import java.util.Map; import java.util.function.BiConsumer; public class User { private String user_Id_1; private String user_Id_2; private String user_Id_3; private String user_Id_4; // 用方法引用初始化序号到setter的映射 private static final Map<Integer, BiConsumer<User, String>> SETTER_MAP = Map.of( 1, User::setUser_Id_1, 2, User::setUser_Id_2, 3, User::setUser_Id_3, 4, User::setUser_Id_4 ); public void setUserId(int num, String userId) { BiConsumer<User, String> setter = SETTER_MAP.get(num); if (setter != null) { setter.accept(this, userId); } else { throw new IllegalArgumentException("无效的序号:" + num); } } // 原有setter方法保持不变 public void setUser_Id_1(String user_Id_1) { this.user_Id_1 = user_Id_1; } public void setUser_Id_2(String user_Id_2) { this.user_Id_2 = user_Id_2; } public void setUser_Id_3(String user_Id_3) { this.user_Id_3 = user_Id_3; } public void setUser_Id_4(String user_Id_4) { this.user_Id_4 = user_Id_4; } }
新增序号时仅需在SETTER_MAP中添加对应条目,代码简洁易维护。
3. 反射实现(适合字段极多的场景)
如果字段数量极大,手动维护映射成本过高,可利用反射根据字段名拼接setter方法名来调用:
import java.lang.reflect.Method; public class User { private String user_Id_1; private String user_Id_2; private String user_Id_3; private String user_Id_4; public void setUserId(int num, String userId) { try { // 按JavaBean规范拼接setter方法名 String fieldName = "user_Id_" + num; String methodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); Method setterMethod = this.getClass().getMethod(methodName, String.class); setterMethod.invoke(this, userId); } catch (Exception e) { throw new IllegalArgumentException("无效的序号:" + num, e); } } // 原有setter方法保持不变 public void setUser_Id_1(String user_Id_1) { this.user_Id_1 = user_Id_1; } public void setUser_Id_2(String user_Id_2) { this.user_Id_2 = user_Id_2; } public void setUser_Id_3(String user_Id_3) { this.user_Id_3 = user_Id_3; } public void setUser_Id_4(String user_Id_4) { this.user_Id_4 = user_Id_4; } }
注意反射存在一定性能损耗,且需保证字段名与setter方法严格遵循JavaBean规范,适合字段数量极多且频繁新增的场景。
内容的提问来源于stack exchange,提问作者Kishore_2021
相关产品推荐
相关产品推荐

