Java for循环内嵌if语句意外无限循环问题排查与实现优化
问题说明
功能要求
实现spinWords字符串处理方法,规则为:反转句子中长度为5及以上的单词,长度不足5的单词保持原顺序和内容不变。
- 输入示例:
"Who lives in a pineapple under the sea?" - 预期输出:
"Who sevil in a elppaenip rednu the sea?"
故障表现
编写的代码运行时出现意外无限循环,初步排查判断问题出在if语句块,但无法定位具体根因;曾尝试将if语句块内的代码直接放到main方法中运行,可正常执行。
问题代码
public class Testing { public static void main(String[] args) { String sentence = "Who lives in a pineapple under the sea?"; System.out.println(spinWords(sentence)); } public static String spinWords(String sentence) { String[] words = sentence.split(" "); int length = words.length; String spinned = ""; for (int i = 0; i < length; i++) { String word = words[i]; int wlength = word.length(); if (wlength > 4) { String reversed = ""; for (i = wlength - 1; i >= 0; i--) { reversed += "" + word.charAt(i); } spinned += reversed + " "; } else { spinned += word + " "; } } spinned = spinned.trim(); return spinned; } }
故障根因
无限循环的核心原因是两层for循环共用了同一个计数器变量i:
- 外层遍历单词数组的循环用
i作为下标计数器,初始值从0开始,自增到等于数组长度时退出 - 内层反转长单词字符的循环,错误地复用了外层的
i作为计数器,每次进入长单词反转逻辑时,i会被重置为当前单词长度-1,内层循环结束后i的值为-1 - 内层循环结束回到外层循环判断条件前,会执行外层循环的
i++,此时i从-1变回0,永远无法增长到等于单词数组长度,因此触发无限循环。
把if块代码挪到main里能正常跑,是因为当时没有嵌套两层共用计数器的循环结构,所以没触发问题。
修复方案
将内层反转字符循环的计数器换成独立变量(比如j)即可,修复后的核心逻辑:
public static String spinWords(String sentence) { String[] words = sentence.split(" "); int length = words.length; String spinned = ""; for (int i = 0; i < length; i++) { String word = words[i]; int wlength = word.length(); if (wlength > 4) { String reversed = ""; // 替换为独立计数器j,避免污染外层循环下标 for (int j = wlength - 1; j >= 0; j--) { reversed += word.charAt(j); } spinned += reversed + " "; } else { spinned += word + " "; } } spinned = spinned.trim(); return spinned; }
更优实现参考
原写法手动拼接字符串、手动实现反转逻辑的效率较低,代码也比较冗余,可以直接借助JDK内置能力简化实现:
// 需提前导入 java.util.Arrays、java.util.stream.Collectors 包 public static String spinWords(String sentence) { return Arrays.stream(sentence.split(" ")) .map(word -> word.length() >= 5 ? new StringBuilder(word).reverse().toString() : word) .collect(Collectors.joining(" ")); }
这个实现的优势:
- 不用手动维护循环计数器,从根源避免计数器混用的低级错误
- 用
StringBuilder内置的reverse()方法实现字符反转,不用自己逐字符拼接 - 用流的
joining()方法做字符串拼接,比反复用+拼接String的性能高很多,代码可读性也更好
内容的提问来源于stack exchange,提问作者Genczar Lawrenz Tomines
相关产品推荐
相关产品推荐

