我有这段代码来测试链表和数组列表之间的性能:
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代码上做错了什么,或者这里有一些特别的东西要学习!对不起,如果我写错了英文:(
答案 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.remove
:remove(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
这适用于ArrayList
和LinkedList