Java中的循环异常

时间:2017-11-21 16:24:50

标签: java linked-list

我有这段代码来测试链表和数组列表之间的性能:

long start = System.currentTimeMillis();
for (int i = 0; i < 1E5; i++) {
    list.add(i);
}

for (int i = 0; i < 1E5; i++) {
    list.remove(i);
}

long end = System.currentTimeMillis();

System.out.println(type + ":" + (end - start));

但后来我收到了这个错误:

  

线程“main”中的异常java.lang.IndexOutOfBoundsException:Index:   50000,尺寸:50000

我很困惑。所以我打开我的Visual Studio并试图用c#做同样的事情:

List<int> numbers = new List<int>();
for (int i = 0; i < 1E5; i++)
{
    numbers.Add(i);
}

for (int i = 0; i < 1E5; i++)
{
    numbers.Remove(i);
}

Console.WriteLine("It's done");

运行得很好。所以我在java代码上做错了什么,或者这里有一些特别的东西要学习!对不起,如果我写错了英文:(

5 个答案:

答案 0 :(得分:5)

remove(int)删除给定索引处的项目, 并且你想调用.NET所做的remove(Object)

list.add(Integer.valueOf(i));
list.remove(Integer.valueOf(i));

旧答案

删除时,大小会发生变化,最后在i = 0时只有一个元素, 但你要删除100000-1。

for (int i = 0; i < 1E5; i++) {
    list.remove(i);
}

要么

for (int i = 0; i < 1E5; i++) {
    list.remove(0);
}

for (int i = 0; i < 1E5; i++) {
    list.remove(list.size() - 1);
}

for (int i = 0; i < 100_000; i++) {
    list.remove(i % list.size());
}

答案 1 :(得分:1)

在Java中,有两个版本的List.removeremove(T),它删除了给定的对象,无论它出现在什么索引处,还有remove(int)删除了那个对象。指数。如果你有一个List<Integer>,这两个方法有点模棱两可,但如果你只是传递一个int,它将使用remove(int),它会失败,因为删除后该索引不再存在列表的一半。

    List<Integer> list = new LinkedList<>();
    for (int i = 0; i < 3; i++) {
        list.add(i);
        System.out.println(list);
    }
    for (int i = 0; i < 3; i++) {
        list.remove(i);  // ERROR!
        System.out.println(list);
    }

如果您要删除 i,而不是 index i中的元素,请转换为Integer

    for (int i = 0; i < 3; i++) {
        list.remove((Integer) i); // works fine
        System.out.println(list);
    }

答案 2 :(得分:0)

在移除循环中,您可以使用list.removeLast()list.remove(0)list.removeFirst()。当我增加列表大小减少时,从中删除元素。所以你的代码将运行到列表的一半,然后才会存在第i个元素。

答案 3 :(得分:0)

您的问题是,当您在同一时间删除元素时,您将以固定数组长度循环

在删除而不是while时,请考虑使用for循环,如下所示:

List<Integer> numbersArrayList = new ArrayList<Integer>();
List<Integer> numbersLinkedList = new LinkedList<Integer>();

int E5 = 500000;

// For Array List test
double start = System.currentTimeMillis();
for (int i = 0; i < E5; i++) {
    numbersArrayList.add(i);
}
while (!numbersLinkedList.isEmpty()) {
    numbersArrayList.remove(0);
}
double end = System.currentTimeMillis();
System.out.println("Array List: " + (end - start));


// For Linked List test
start = System.currentTimeMillis();
for (int i = 0; i < E5; i++) {
    numbersLinkedList.add(i);
}
while (!numbersLinkedList.isEmpty()) {
    numbersLinkedList.remove(0);
}
end = System.currentTimeMillis();
System.out.println("linked List: " + (end - start));  

答案 4 :(得分:0)

如果你真的想通过迭代列表来删除元素,那么你可以按照以下步骤去做。

List<Integer> list = new LinkedList<>();

for (int i = 0; i < 1000; i++) {
    list.add(i);
}

for (int i = 1000 - 1; i >= 0; i--) {
    list.remove(i);
}

我在这里做的是我按相反的顺序迭代。所以它总是删除最后一个元素,永远不会抛出java.lang.IndexOutOfBoundsException

这适用于ArrayListLinkedList