如何在使用StringBuilder时通过循环精简多段switch语句?
看起来你是在处理类似电话键盘的字符转数字映射,而且重复写了多段几乎一样的switch语句——这确实是代码重复的典型场景,我们可以用映射表+循环来彻底精简代码。
先拆解你的重复逻辑:每段switch都是做同一件事:针对某个索引位置的字符,判断它属于哪个字母组,然后替换成对应的数字。那我们可以把字母到数字的映射抽离出来,再用循环遍历所有需要处理的索引即可。
第一步:创建字符到数字的映射表
我们可以用一个数组来实现高效的查找(因为字符的ASCII值是连续的,数组比HashMap更快),对应电话键盘的字母映射:
import java.util.Arrays; public class YourClassName { // 初始化字符到数字的映射,覆盖所有小写字母,默认用'0'表示无映射 private static final char[] CHAR_TO_DIGIT = new char[128]; static { // 初始化默认值 Arrays.fill(CHAR_TO_DIGIT, '0'); // 按电话键盘分组映射 mapCharsToDigit("abc", '2'); mapCharsToDigit("def", '3'); mapCharsToDigit("ghi", '4'); mapCharsToDigit("jkl", '5'); mapCharsToDigit("mno", '6'); mapCharsToDigit("pqrs", '7'); mapCharsToDigit("tuv", '8'); mapCharsToDigit("wxyz", '9'); } // 辅助方法,批量映射字符到数字 private static void mapCharsToDigit(String chars, char digit) { for (char c : chars.toCharArray()) { CHAR_TO_DIGIT[c] = digit; } }
第二步:用循环替代重复的switch
原来的6段switch对应6个不同的索引(比如从4开始依次递增到9),我们只需要把这些索引列出来,用循环遍历处理每个位置即可。而且你原来的insert+delete操作其实等价于直接替换字符,用setCharAt更高效简洁:
public static String convert(String str) { StringBuilder strb = new StringBuilder(str); // 定义需要处理的所有索引(根据你的需求调整,这里假设是4到9共6个) int[] targetIndices = {4, 5, 6, 7, 8, 9}; for (int idx : targetIndices) { char originalChar = strb.charAt(idx); // 如果需要支持大写字母,可以先转小写:originalChar = Character.toLowerCase(originalChar); char mappedDigit = CHAR_TO_DIGIT[originalChar]; // 只有当字符有对应映射时才替换(如果不需要保留原字符,可去掉判断) if (mappedDigit != '0') { strb.setCharAt(idx, mappedDigit); } } return strb.toString(); } }
额外优化:处理连续索引
如果你的目标索引是连续的(比如从4到9是连续6个位置),还可以直接用范围循环替代数组,代码更简洁:
// 处理从索引4开始的连续6个位置 int startIdx = 4; for (int idx = startIdx; idx < startIdx + 6; idx++) { // 同上的字符替换逻辑 }
为什么这样更优?
- 消除代码重复:原来的6段switch现在变成了几行循环代码,后续要修改映射规则或新增处理索引,只需要调整映射表或索引范围即可。
- 性能更好:数组查找比多次switch判断更快,而且
setCharAt比insert+delete减少了字符串的操作次数。 - 可读性更强:映射关系集中管理,逻辑一目了然。
内容的提问来源于stack exchange,提问作者Rye Guy
相关产品推荐
相关产品推荐

