Java中遍历List调用set()抛出数组越界异常的原因?
问题分析与修复方案
嘿,我来帮你拆解下这个问题的根源,以及怎么快速解决~
为什么会抛出ArrayIndexOutOfBoundsException?
最可能的原因有两个,核心都和你调用indexOf(c)的逻辑有关:
CP类未正确重写equals()和hashCode()indexOf()方法是通过equals()来匹配元素的。如果你的CP类没重写这两个方法,默认会用引用相等来判断;或者你重写了,但equals()的逻辑依赖了m_midRate这个会被修改的属性——当你执行c.setM_midRate(value)之后,再调用indexOf(c),此时对象的属性已经变化,equals()匹配失败,indexOf()会返回-1,接着调用cp.set(-1, c)自然就会抛出数组越界异常。- 完全多余的
set()操作
其实你根本不需要把修改后的c重新放回列表!因为增强for循环里的c本身就是列表中对应元素的引用,你直接调用c.setM_midRate(value)修改属性,这个变化会直接反映到列表里的对象上,set()步骤纯粹画蛇添足,反而引入了风险。
修复方案(按推荐程度排序)
方案1:删掉多余的indexOf和set操作(最推荐)
这是最简单高效的解决方式,直接修改引用对象的属性即可:
for(CP c : cp) { c.setM_midRate(value); } cpp.setCP(cp);
方案2:改用普通for循环(避免indexOf的坑)
如果你习惯用索引遍历,直接通过索引获取元素,完全不需要查找索引:
for(int i = 0; i < cp.size(); i++) { CP c = cp.get(i); c.setM_midRate(value); // 这里完全不需要cp.set(i, c),修改属性已经生效 } cpp.setCP(cp);
方案3:正确重写CP类的equals()和hashCode()(长期规范)
如果后续你的代码需要用到indexOf、contains等集合查找方法,一定要确保CP类的相等判断逻辑不依赖可变属性。比如用唯一标识字段(如id)来重写:
import java.util.Objects; public class CP { private Long id; // 假设这是唯一标识 private double m_midRate; // 其他字段、getter、setter @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; CP cp = (CP) o; return Objects.equals(id, cp.id); } @Override public int hashCode() { return Objects.hash(id); } }
这样即使修改了m_midRate,indexOf(c)也能正确找到元素索引,不会返回-1。
内容的提问来源于stack exchange,提问作者Shagufta Oliveyu Methwani
相关产品推荐
相关产品推荐

