【问题标题】:Container.remove(int i) throws unexpected ArrayIndexOutOfBoundsExceptionContainer.remove(int i) 抛出意外的 ArrayIndexOutOfBoundsException
【发布时间】:2010-11-28 00:45:07
【问题描述】:

我正在尝试从 Java 容器中删除除第一个子组件之外的所有子组件。以下代码记录“有 3 个”并抛出 ArrayIndexOutOfBoundsException: Array index out of range: 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) 似乎无法就容器中的组件数量达成一致。有没有其他人遇到过这个问题?

【问题讨论】:

    标签: java components containers


    【解决方案1】:

    当你在做 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);
    }
    

    【讨论】:

      【解决方案2】:

      索引从 0 开始,三项表示第一项在索引 0 处,第二项在索引 1 处,第三项在索引 2 处。

      【讨论】:

        【解决方案3】:

        Container.remove(int i) 删除索引 i 处的项目

        您的代码删除了 1,2,3 处的项目

        【讨论】:

          【解决方案4】:

          Benny 的回答是正确的,但是根据容器的不同,它可能效率低下。像ArrayList 这样的东西并不喜欢多次从前面删除东西,因为它每次都会复制所有其余的数据。

          这里有一个替代方案:

          for (int i = cardPanel.getComponentCount() - 1; i >= 1; i--)
          {
              cardPanel.remove(i);
          }
          

          基本上这是从结尾开始,并朝着开始的方向努力。

          这只会对大型收藏有意义,但值得了解这项技术。

          【讨论】:

            【解决方案5】:

            你想做什么?如果您想从容器中删除所有项目,那么removeAll 是正确的选择。

            如果您需要在移除时处理项目,那么典型的习惯用法是从头到尾,正如 Jon Skeet 解释的那样。

            除非你必须从 0 到结束,在这种情况下你会一直删除第 0 个元素:

            for (int i = 0; i < componentCount; i++) {
                cardPanel.remove(0);
            }
            

            【讨论】:

              【解决方案6】:

              如果您想根据索引上的某些条件删除项目,最好使用显式迭代器来删除它们,同时保留您自己的索引计数。

              例如,删除奇数索引处的所有对象:

                  int index = 0;
                  final Iterator<String> iterator = list.iterator();
                  while (iterator.hasNext())
                  {
                      iterator.next();
                      if (index % 2 != 0)
                      {
                          iterator.remove();
                      }
                      index++;
                  }
              

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

              【讨论】:

              • 不幸的是,这在从容器中删除子组件的上下文中是不可能的,因为无法将子组件检索为可变列表。
              猜你喜欢
              • 2016-11-09
              • 2023-03-16
              • 1970-01-01
              • 1970-01-01
              • 2012-04-12
              • 2013-05-10
              • 1970-01-01
              • 1970-01-01
              • 2019-09-12
              相关资源
              最近更新 更多