在ArrayList中存储同一父类多子类实例及索引越界异常解决咨询
问题根源
- 第一处逻辑错误:外层循环条件为
while (this.theArrayList.size() == 0),进入循环时theArrayList是空集合,内层的while (this.theArrayList.toArray().length > i)永远不满足执行条件,整个循环体没有任何能修改theArrayList长度的逻辑,直接触发死循环。 - 第二处逻辑错误:即使
anArrayListOfAFromPreviousCodeBlock为空,你只是弹出了提示,没有终止后续的get(randomIndex)操作,此时集合长度为0,取任何下标都会抛出IndexOutOfBoundsException。 - 第三处遗漏操作:你初始化了
theArrayList但没有把B、C、D等子类的实例添加到这个集合中,集合自然始终为空。 - 关于你怀疑的类型兼容问题:
ArrayList<A>可以正常存储所有继承自A的子类实例,不存在类型不兼容问题,这个怀疑不成立。
修复方案
- 先将所有需要处理的B、C、D等子类实例添加到
theArrayList中,保证集合不为空再执行后续逻辑。 - 调整循环顺序,先遍历
theArrayList筛选符合条件的元素存入anArrayListOfAFromPreviousCodeBlock,筛选完成后再判断该集合是否为空,不为空再执行随机抽取逻辑。 - 打乱集合顺序可以直接调用
Collections.shuffle()方法,不需要自己写随机抽取逻辑,更简洁也避免下标错误。
修正后的代码示例
首先是类成员定义:
// 类作用域定义 ArrayList<A> theArrayList = new ArrayList<>(); ArrayList<A> anArrayListOfAFromPreviousCodeBlock = new ArrayList<>(); ArrayList<A> thisArrayList = new ArrayList<>(); // 你代码中用到的目标集合,记得初始化 int wealth = 100; // 替换为你自己的wealth赋值逻辑
然后是构造函数中的处理逻辑:
// 第一步:先把所有B、C、D等子类实例添加到theArrayList,示例如下 theArrayList.add(new B()); theArrayList.add(new C()); theArrayList.add(new D()); // 有多少实例就加多少,所有A的子类实例都可以正常存入ArrayList<A> // 第二步:筛选price大于wealth的元素 for (A a : theArrayList) { if (a.price > this.wealth) { anArrayListOfAFromPreviousCodeBlock.add(a); } } // 第三步:判断筛选结果是否为空 if (anArrayListOfAFromPreviousCodeBlock.isEmpty()) { JOptionPane.showMessageDialog(null, "没有符合条件的元素!"); return; // 直接终止后续逻辑,避免下标越界 } // 第四步:打乱集合顺序,替代自定义随机抽取逻辑,避免顺序偏差 Collections.shuffle(anArrayListOfAFromPreviousCodeBlock); // 第五步:把打乱后的元素存入目标集合,之后即可绑定到JTable展示 thisArrayList.addAll(anArrayListOfAFromPreviousCodeBlock);
后续绑定JTable时,你可以自定义TableModel,将thisArrayList作为数据源,直接读取A类的公共属性展示即可。
内容的提问来源于stack exchange,提问作者GalliadII
相关产品推荐
相关产品推荐

