You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

执行to.charAt()遇索引越界-1,为何误解s.charAt()返回-1?

Java字符串转换时的索引越界错误分析

原代码

public class Main {
    public static void main(String[] args) {
        System.out.println(tr("November 2016","abcdefghijklmnopqrstuvwyz","ABCDEFGHIJKLMNOPQRSTUVWYZ"));
    }

    public static String tr(String s, String from, String to){
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < s.length(); i++){
            if (from.contains(s.substring(i, i + 1)) || to.contains(s.substring(i, i + 1))){
                sb.append(to.charAt(to.indexOf(s.charAt(i))));
            }else {
                sb.append(s.charAt(i));
            }
        }
        return sb.toString();
    }
}

问题现象

执行sb.append(to.charAt(to.indexOf(s.charAt(i))));时触发**索引越界:-1(数组长度为25)**错误,疑惑为什么s.charAt(i)会返回-1(预期返回1)。

错误根源

首先纠正:s.charAt(i)不会返回-1,它返回的是字符对应的Unicode码点(比如'o'返回111)。真正的问题是to.indexOf(s.charAt(i))返回了-1,调用charAt(-1)才触发索引越界。

举个具体例子:当遍历到"November"里的小写'o'时,from.contains("o")结果为true,进入分支逻辑。但to字符串里只有大写字母,to.indexOf('o')找不到对应字符,返回-1,此时to.charAt(-1)直接触发索引越界异常。

另外你的from和to字符串都遗漏了字母x/X,这是潜在问题,不过本次报错并非由此导致。

修复方案

核心逻辑错误是:应该先找到字符在from中的索引,再用该索引去to中取对应字符,而不是直接在to中查找原字符(大小写不匹配必然找不到)。修复后的代码如下:

public class Main {
    public static void main(String[] args) {
        // 补全from和to中的x/X,避免遗漏字符
        System.out.println(tr("November 2016","abcdefghijklmnopqrstuvwxyz","ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
    }

    public static String tr(String s, String from, String to){
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < s.length(); i++){
            char currentChar = s.charAt(i);
            int fromIndex = from.indexOf(currentChar);
            int toIndex = to.indexOf(currentChar);

            if (fromIndex != -1) {
                // 字符在from中,取to对应索引的字符完成转换
                sb.append(to.charAt(fromIndex));
            } else if (toIndex != -1) {
                // 字符在to中,可根据需求转成from对应字符(比如大写转小写)
                sb.append(from.charAt(toIndex));
            } else {
                // 字符不在from/to中,直接保留
                sb.append(currentChar);
            }
        }
        return sb.toString();
    }
}

修复点说明

  1. 先获取字符在from和to中的索引,避免重复调用substring和contains,提升代码效率。
  2. 当字符在from中时,用from的索引匹配to的对应位置,解决大小写不匹配导致的查找失败问题。
  3. 补全from和to中的x/X,消除潜在的字符遗漏问题。
  4. 拆分分支逻辑,明确处理不同场景,代码可读性更强。

内容的提问来源于stack exchange,提问作者Shulhin Denys

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 05:05:16