Container.remove(int i)抛出意外的ArrayIndexOutOfBoundsException

时间:2009-09-14 05:01:15

标签: java components containers

我正在尝试从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)无法就容器中的组件数达成一致。还有其他人遇到过这个问题吗?

6 个答案:

答案 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++;
    }

虽然这有点长,但它避免了棘手的代码,并且当列表中有相同的对象时也可以工作。