【问题标题】:Arraylist java.lang.IndexOutOfBoundsException: Index 3 out of bounds for length 3 ErrorArraylist java.lang.IndexOutOfBoundsException:索引 3 超出长度 3 错误的范围
【发布时间】:2021-04-09 03:49:45
【问题描述】:

我创建了一个方法,它接受一个Arraylist 的字符串和一个整数。它将删除所有长度小于给定整数的字符串。

例如:

Arraylist = ["abcde", "aabb", "aaabbb", "abc", "ab"]

整数 = 4

所以新的Arraylist 应该是:["abcde", "aabb", "aaabbb"]

但我收到此错误消息:

线程“main”java.lang.IndexOutOfBoundsException 中的异常:索引 3 超出长度 3 的范围

这是我的代码:

public static void main(String[] args){
        ArrayList<String> newArrayList = new ArrayList<>();
        newArrayList.add("string1");
        newArrayList.add("string2");
        newArrayList.add("rem");
        newArrayList.add("dontremove");
        removeElement(newArrayList, 4); // new arraylist must be = [string1, string2, dontremove]
    }


    public static void removeElement(ArrayList<String> arraylist, int inputLen){
        int arrayLen = arraylist.size();
        for(int i=0; i<arrayLen; i++){
            if(arraylist.get(i).length() < inputLen){
                arraylist.remove(i);
                i--;
            }
        }
        System.out.println("New Arraylist: " + arraylist);
    }

这段代码有什么问题?

【问题讨论】:

  • 除了您的逻辑错误之外,名称removeElement 表示您的方法将删除第四个元素。相反,像removeElementsLongerThan 这样的名称对阅读您的代码的人更有帮助。此外,您通常不应将变量和参数声明为ArrayListjust use List.

标签: java arraylist indexoutofboundsexception


【解决方案1】:
int arrayLen = arraylist.size();

问题是您的索引值为 4。

但是,一旦您从列表中删除一个项目,您现在只有 3 个条目。

因此,在您的循环中,当您尝试访问第 4 个条目时,您现在将收到 IndexOutOfBounds 错误。

解决办法是从ArrayList的末尾开始倒数到0。

For (int i = arrayLen - 1; i >= 0; i--)

在循环内你不需要:

i--;

【讨论】:

  • 不,解决方案是使用迭代器。你的提案仍有可能抛出ConcurrentModificationException
  • @chrylis-cautiouslyoptimistic-,不,它不会抛出 ConcurrentModificationException。它没有使用 foreach。代码所做的只是访问 ArrayList 中的一个项目。 ArrayList 不知道也不关心代码是否在循环中执行。
【解决方案2】:

您正在从 0 循环到数组的大小,即 4。在循环内,您正在删除项目,因此数组的大小变得小于 4,因此您会遇到此异常。 尝试像这样循环:

Iterator<String> iterator = arraylist.iterator();

while (iterator.hasNext()) {
    String word = iterator.next();
    if (word.length() < inputLen) {
        iterator.remove();
    }
}

【讨论】:

  • 是的,我知道这就像解决这个问题的不同方法。但我想用我使用的方式解决这个问题。就像使用“for”语句一样。非常感谢您的帮助。
  • @erenoz 如果您想使用“for”循环,请不要在循环时更改您正在循环的列表。在循环内部,您可以将要删除的项目添加到新列表中,然后在“for”循环之后将其删除。
【解决方案3】:

当你删除元素时,数组的长度应该会改变。 arrayLen 变量存储数组的长度,但当数组长度缩小时不会改变。要更改它,您应该能够将 arrayLen 替换为 arrayList.size(),当您删除元素时,它会改变

【讨论】:

    【解决方案4】:

    您正在修改列表,同时迭代其索引。删除第一项后,列表将比您预期的要短,一旦到达原始最后一个元素的索引,您将收到此错误。幸运的是,removeIf 方法可以为您完成繁重的工作:

    public static void removeElement(List<String> arraylist, int inputLen) {
        arraylist.removeIf(s -> s.length() < inputLen);
        System.out.println("New Arraylist: " + arraylist);
    }
    

    【讨论】:

    • 正确,但是 OP 的整体代码风格表明实现removeIf 的功能是练习的重点。
    猜你喜欢
    • 1970-01-01
    • 2020-12-05
    • 2017-12-07
    • 2021-02-03
    • 2017-05-30
    • 1970-01-01
    • 2021-07-05
    • 2019-08-24
    • 2019-10-30
    相关资源
    最近更新 更多