遍历双数组的Java循环为何抛出java.lang.IndexOutOfBoundsException异常?
解决你的
IndexOutOfBoundsException问题 首先咱们先拆解问题核心——你的循环逻辑存在漏洞,这才是触发越界异常的根本原因,而它只在部分电脑出现的现象,大概率是因为那些环境下两个集合的元素数量没对齐导致的。
问题到底出在哪?
先看你这段循环代码的关键逻辑:
for(int i = 0; i < arrayList.size()-1;) { for(int j = 0; j < arrayList2.size()-1;) { // ...绘图操作 g2d.drawLine(arrayList.get(i), arrayList2.get(j), arrayList.get(i+1), arrayList2.get(j+1)); i++; j++; } }
这里有两个致命问题:
- 你把
i++和j++放在了内层循环里,意味着每次执行内层循环,两个计数器会同时递增,但内层循环的终止条件只判断j的状态,完全忽略i是否已经超出arrayList的范围。如果arrayList比arrayList2短,那j还没到终止值时,i就会先触达arrayList.size()-1,下一次i++后,i+1直接超出集合最大索引,抛出异常。 - 反过来,如果
arrayList2更短,内层循环结束后外层循环还会继续执行,此时j已经是arrayList2.size()-1,再执行j++的话,后续访问arrayList2.get(j)或j+1也会触发越界。 - 另外,用
size()-1作为循环边界本身就有风险:如果集合为空,size()-1会变成-1;如果集合只有1个元素,循环根本不会执行,但只要两个集合长度差1,就一定会触发越界。
怎么修复?
你要实现的应该是按对应索引遍历两个集合,绘制连续线段,对吧?那正确的做法是用单个循环,以两个集合中较短的长度-1作为终止条件,从根源避免索引越界:
BufferedImage img = new BufferedImage(screenWidth, screenHeight, BufferedImage.TYPE_INT_RGB); Graphics2D g2d = img.createGraphics(); // 取两个集合中较小的长度,减1是因为要访问i+1索引 int maxValidIndex = Math.min(arrayList.size(), arrayList2.size()) - 1; // 单个循环同时遍历两个集合的对应索引 for(int i = 0; i < maxValidIndex; i++) { g2d.setColor(col); g2d.setStroke(new BasicStroke(1)); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.drawLine(arrayList.get(i), arrayList2.get(i), arrayList.get(i+1), arrayList2.get(i+1)); } // 别忘了释放Graphics资源,避免内存泄漏 g2d.dispose();
再补充几个优化&规范点:
- 把
setColor、setStroke这些渲染设置放在循环外面,不用每次循环重复执行,对4万+元素的大集合来说,能明显提升性能。 - 如果你的业务逻辑要求两个坐标集合必须长度完全一致,建议在循环前加校验,提前暴露问题:
if(arrayList.size() != arrayList2.size()) { throw new IllegalArgumentException("两个坐标集合的长度必须完全一致!"); }
为什么只在部分电脑出现?
核心原因是那些环境下两个集合的元素数量不一致——比如数据加载时偶尔少了一个元素,或者多生成了一个坐标,导致两个集合长度差1,刚好触发了循环的越界漏洞;而其他电脑上两个集合长度完全匹配,所以没出现异常。
内容的提问来源于stack exchange,提问作者rgadhia12
相关产品推荐
相关产品推荐

