Java字符串指定字符加括号高亮实现方法的优化咨询
Java字符高亮方法优化点
现有代码核心问题
- 命名可读性极差:
arg1、arg2、a、b这类无意义命名,维护成本极高 - 时间效率低下:两层嵌套循环实现匹配,时间复杂度为
O(n*m)(n为输入字符串长度、m为待匹配字符数组长度),待匹配字符量大时性能下降明显 - 数组长度计算逻辑错误:最坏情况每个字符都需要包裹括号,单字符占用长度为3(
(x)),原有逻辑原长度*2 + 字符数组长度无法覆盖最坏场景,存在数组下标越界风险 - 返回结果异常:直接用完整的预申请字符数组构造字符串,数组未使用的位置会填充不可见空字符
\u0000,导致输出结果不符合预期 - 逻辑冗余+边界缺失:空格判断放在内层循环重复执行,没有处理空输入等边界场景,存在空指针风险
具体优化方案
1. 高性能优化版(保留数组操作,修复所有问题)
static String highlightCharsInString(String inputStr, char[] charsToHighlight) { // 边界校验,空输入直接返回 if (inputStr == null || inputStr.isEmpty() || charsToHighlight == null || charsToHighlight.length == 0) { return inputStr; } // 用ASCII布尔表实现O(1)匹配,提前排除空格 boolean[] matchTable = new boolean[128]; for (char c : charsToHighlight) { if (c != ' ') { matchTable[c] = true; } } char[] inputChars = inputStr.toCharArray(); // 按最坏情况申请3倍长度数组,避免越界 char[] hlChars = new char[inputChars.length * 3]; int writePos = 0; for (char cur : inputChars) { if (cur != ' ' && matchTable[cur]) { hlChars[writePos++] = '('; hlChars[writePos++] = cur; hlChars[writePos++] = ')'; } else { hlChars[writePos++] = cur; } } // 只取实际写入的长度,避免冗余空字符 return new String(hlChars, 0, writePos); }
若需要支持全Unicode字符匹配,将
boolean[] matchTable替换为HashSet<Character>即可,匹配逻辑保持一致。
2. 简洁易维护版(用StringBuilder简化操作)
如果不需要极致的性能,用StringBuilder可以省去手动管理数组下标、申请数组长度的步骤,代码更简洁:
static String highlightCharsInString(String inputStr, char[] charsToHighlight) { if (inputStr == null || inputStr.isEmpty() || charsToHighlight == null || charsToHighlight.length == 0) { return inputStr; } boolean[] matchTable = new boolean[128]; for (char c : charsToHighlight) { if (c != ' ') { matchTable[c] = true; } } StringBuilder sb = new StringBuilder(inputStr.length() * 3); for (char cur : inputStr.toCharArray()) { if (cur != ' ' && matchTable[cur]) { sb.append('(').append(cur).append(')'); } else { sb.append(cur); } } return sb.toString(); }
优化后收益
- 时间复杂度从
O(n*m)降到O(n+m),待匹配字符越多性能提升越明显 - 修复了数组越界、返回结果带空字符的功能性bug
- 代码可读性、可维护性大幅提升
- 覆盖了所有边界输入场景,避免空指针异常
内容的提问来源于stack exchange,提问作者Laghorn
相关产品推荐
相关产品推荐

