Java ArrayList统计重复字符时触发IndexOutOfBoundsException问题
问题根源
抛出IndexOutOfBoundsException的核心原因是原字符串索引和ArrayList列表索引的映射逻辑完全错误,附带存在首个字符漏统计的问题:
- 内层循环的变量
j是原字符串comb的遍历索引,范围是0到i-1,但代码直接用j作为索引去访问list。实际上list只存储首次出现的不重复字符,长度远小于已遍历的原字符串长度,当j大于等于list.size()时,调用list.get(j)必然触发索引越界。 - 外层循环初始值设为
i=1,原字符串索引为0的第一个字符从未被加入list,从统计逻辑上直接漏掉了首个字符的计数。
可行修复方案
调整遍历匹配逻辑,不再用原字符串索引直接访问列表,改为遍历列表匹配存储的字符值,具体修改点:
- 外层循环从
i=0开始遍历完整字符串,避免漏掉首个字符 - 判断字符是否重复时,遍历当前
list的所有元素,对比元素中存储的字符值,而非对比原字符串j位置的字符 - 匹配到重复字符时直接给对应元素计数+1,未匹配到则新增letter对象存入列表
修复后的可运行代码如下:
import java.util.ArrayList; public class CharCountTest { public static void main(String[] args) { ArrayList<letter> list = new ArrayList<letter>(); String comb = "hhhoofdpsdshodss"; for(int i = 0; i<comb.length(); i++){ char currentChar = comb.charAt(i); boolean finded = false; // 遍历已有列表查找是否存在当前字符 for(int j=0; j < list.size(); j++){ if(list.get(j).getLetter() == currentChar){ list.get(j).upCounter(); finded = true; break; } } // 没找到重复则新增记录 if(!finded){ list.add(new letter(currentChar)); } } // 输出统计结果 for(int i = 0; i<list.size() ; i++){ System.out.println((char)list.get(i).getLetter() + ": " + list.get(i).getCounter()); } } } class letter{ private char let; int counter= 0; public letter(char character){ let=character; counter++; } public int getCounter(){ return counter; } public void upCounter(){ counter++; } public int getLetter(){ return let; } }
运行后输出结果为:
h: 4 o: 3 f: 1 d: 3 p: 1 s: 5
注:原letter类的
getLetter()方法返回值为int类型,是char自动类型提升导致,不影响功能逻辑,如果要代码更规范,可以将返回值修改为char类型,输出时就不需要强转。
内容的提问来源于stack exchange,提问作者Cerme09
相关产品推荐
相关产品推荐

