Java中使用lastIndexOf触发IndexOutOfBoundsException问题求助
问题分析与解决思路
首先,咱们来拆解你遇到的IndexOutOfBoundsException问题:
错误根源
索引越界的直接原因:
你的第二个循环里使用了list.get(i + n - 1),但list的大小是ss.length() - n + 1(这里处理后的ss长度是10,n=4,所以list有7个元素,索引范围0~6)。当i取值到4时,i + n -1 = 4 + 4 -1 =7,而list的最大索引是6,这就触发了索引越界异常。逻辑设计的深层问题:
你试图通过ss.indexOf(list.get(i))和ss.lastIndexOf(...)来获取子序列的索引范围,这是不可靠的——如果原字符串中有重复的子序列,indexOf会返回第一个匹配的位置,而不是当前子序列的真实起始索引,会导致索引范围显示错误。
解决思路
其实每个子序列的索引范围完全可以直接通过循环变量计算出来,根本不需要绕弯子去list里查找:
- 对于第i个循环(从0开始),子序列的起始索引就是
i - 结束索引则是
i + n -1(因为子序列长度是n,从i到i+n-1共n个字符)
修正后的代码
方式1:保留list存储子序列(适合后续需要复用子序列的场景)
import java.util.ArrayList; public class Subsequences { public static void main(String[] args) { String s = "CCAATA CCGT"; ArrayList<String> list = new ArrayList<String>(); int n = 4; String ss = s.replaceAll("\\s+", ""); // 生成子序列并存储 for (int i = 0; i <= ss.length() - n; i++) { String substr = ss.substring(i, i + n); list.add(substr); } // 输出每个子序列的索引范围和内容 for (int i = 0; i < list.size(); i++) { int startIndex = i; int endIndex = i + n - 1; System.out.println(startIndex + " thru " + endIndex + " : " + list.get(i)); } } }
方式2:直接输出(更高效,无需额外存储list)
如果不需要保留子序列列表,可以直接在生成子序列的循环里输出,节省内存:
public class Subsequences { public static void main(String[] args) { String s = "CCAATA CCGT"; int n = 4; String ss = s.replaceAll("\\s+", ""); for (int i = 0; i <= ss.length() - n; i++) { String substr = ss.substring(i, i + n); int endIndex = i + n - 1; System.out.println(i + " thru " + endIndex + " : " + substr); } } }
运行结果
修正后运行会输出正确的索引范围:
0 thru 3 : CCAA 1 thru 4 : CAAT 2 thru 5 : AATA 3 thru 6 : ATAC 4 thru 7 : TACC 5 thru 8 : ACCG 6 thru 9 : CCGT
内容的提问来源于stack exchange,提问作者CaptainMar
相关产品推荐
相关产品推荐

