使用Java拆分字符串为单词时遭遇堆内存错误问题排查
问题分析与修复
问题根源
你的代码出现堆空间错误,核心原因是while循环无法正常终止,且字符串截取逻辑混乱,导致循环无限执行,不断创建新字符串对象,最终耗尽堆内存。具体问题点:
iter != 0时,修改了原字符串s的引用,但iter的更新逻辑错误,导致循环条件iter < s.length()始终成立,进入死循环。else分支中,s.substring(iter+1,s.indexOf(" "))的索引计算完全错误:此时s已被截取过,原iter值对应的索引在新字符串中可能超出范围,既无法正确拆分单词,还会让循环无法推进。- 最后一个单词未被添加到结果列表,因为当字符串中无空格时直接break,遗漏了剩余内容。
修复后的代码
方案一:修正原while循环逻辑
保留你想用while+substring的思路,调整索引计算和循环推进逻辑:
package pckg; import java.util.ArrayList; public class KeywordMatcher { public static void main(String[] args) { String s_0 = "apple pie bitch cunt whore ass dick big nib crunch"; String s_1 = "john stewart ass loser bitch lee dick cook ally die"; System.out.println(keywordsFromString(s_0)); } public static ArrayList<String> keywordsFromString(String s) { ArrayList<String> ans = new ArrayList<String>(); int start = 0; int spaceIndex = s.indexOf(" "); while (spaceIndex != -1) { // 添加当前找到的单词 ans.add(s.substring(start, spaceIndex)); // 更新起始位置为空格的下一位 start = spaceIndex + 1; // 查找下一个空格的位置 spaceIndex = s.indexOf(" ", start); } // 添加最后一个无后续空格的单词 ans.add(s.substring(start)); return ans; } }
方案二:使用Java内置方法(更简洁健壮)
如果不需要严格依赖while+substring,可以直接用String.split()方法拆分,代码更简洁且能处理连续空格的场景:
public static ArrayList<String> keywordsFromString(String s) { ArrayList<String> ans = new ArrayList<>(); // 按任意数量的空白字符拆分,避免连续空格产生空字符串 String[] words = s.split("\\s+"); for (String word : words) { ans.add(word); } return ans; }
关键修复说明
- 方案一中,通过维护
start和spaceIndex两个变量,精准定位每个单词的起止位置,循环推进逻辑清晰,不会出现死循环,同时补上了最后一个单词的添加逻辑。 - 方案二中的
split("\\s+")可以匹配任意数量的空白字符(空格、制表符等),比直接按单个空格拆分更适配复杂场景。
内容的提问来源于stack exchange,提问作者Dean Loyals
相关产品推荐
相关产品推荐

