我正在尝试从Java容器中删除除第一个子组件之外的所有子组件。以下代码记录“有3”并抛出ArrayIndexOutOfBoundsException:数组索引超出范围:2
int componentCount = cardPanel.getComponentCount();
logger.info("There are " + componentCount);
for (int i = 1; i < componentCount; i++) {
cardPanel.remove(i);
}
然而,这个修改版本完美无缺:
Component[] components = cardPanel.getComponents();
logger.info("There are " + components.length);
for (int i = 1; i < components.length; i++) {
cardPanel.remove(components[i]);
}
似乎Container.getComponentCount()和Container.remove(int i)无法就容器中的组件数达成一致。还有其他人遇到过这个问题吗?
答案 0 :(得分:4)
当您执行cardPanel.remove(i)时,组件数量正在减少。
所以你有[0,1,2],并删除索引1处的项目
现在你有[0,2]并删除索引2处的项目,这会抛出ArrayIndexOutOfBoundsException。
修改后的版本之所以有效,是因为它正在从容器中删除实际对象,而不是从索引中删除。
试试这个
int componentCount = cardPanel.getComponentCount();
logger.info("There are " + componentCount);
for (int i = 1; i < componentCount; i++) {
cardPanel.remove(1);
}
答案 1 :(得分:3)
Benny的回答是正确的,但取决于容器,它可能效率低下。像ArrayList
这样的东西并不像多次从前面删除东西,因为它每次都会复制所有其余的数据。
这是另一种选择:
for (int i = cardPanel.getComponentCount() - 1; i >= 1; i--)
{
cardPanel.remove(i);
}
基本上,这是从结束开始,并朝着开始。
它对于大型收藏品来说只会很重要,但值得了解这项技术。
答案 2 :(得分:0)
索引从0开始,三个项目表示第一个项目位于索引0,第二个项目位于索引1和第三个项目,因此最后一个项目位于索引2处。
答案 3 :(得分:0)
Container.remove(int i)删除索引i
的项目您的代码会删除1,2,3
的项目答案 4 :(得分:0)
你想做什么?如果要从容器中删除所有项目,则removeAll
是正确的选择。
如果你需要在移除时处理这些物品,那么典型的习语是从头到尾,正如Jon Skeet所解释的那样。
除非你必须从0到结尾,否则你会继续删除第0个元素:
for (int i = 0; i < componentCount; i++) {
cardPanel.remove(0);
}
答案 5 :(得分:0)
如果要根据索引上的某些条件删除项目,最好使用显式迭代器删除它们,同时保留自己的索引计数。
例如,要删除奇数索引处的所有对象:
int index = 0;
final Iterator<String> iterator = list.iterator();
while (iterator.hasNext())
{
iterator.next();
if (index % 2 != 0)
{
iterator.remove();
}
index++;
}
虽然这有点长,但它避免了棘手的代码,并且当列表中有相同的对象时也可以工作。