【发布时间】:2011-08-16 07:32:21
【问题描述】:
我在关注previous post,上面写着:
对于链表
- 得到是 O(n)
- 加起来是 O(1)
- 删除是 O(n)
- Iterator.remove 是 O(1)
对于数组列表
- 得到是 O(1)
- add 摊销为 O(1),但最坏情况为 O(n),因为必须调整和复制数组的大小
- 删除是 O(n)
因此,通过查看这一点,我得出结论,如果我只需要在我的集合中按顺序插入 5000000 个元素,LinkedList 将优于 ArrayList。
如果我只需要通过迭代从集合中获取元素,即不抓取中间的元素,LinkedList 仍然会超越 `ArrayList.
现在为了验证我上面的两个陈述,我写了下面的示例程序......但我很惊讶我上面的陈述被证明是错误的。
ArrayList 在这两种情况下都优于 Linkedlist。从 Collection 中添加和获取它们所花费的时间比 LinkedList 少。是不是我做错了什么,或者关于 LinkedList 和 ArrayList 的初始声明对于大小为 5000000 的集合不适用?
我提到了大小,因为如果我将元素数量减少到 50000 个,LinkedList 的性能会更好,并且初始语句成立。
long nano1 = System.nanoTime();
List<Integer> arr = new ArrayList();
for(int i = 0; i < 5000000; ++i) {
arr.add(i);
}
System.out.println( (System.nanoTime() - nano1) );
for(int j : arr) {
;
}
System.out.println( (System.nanoTime() - nano1) );
long nano2 = System.nanoTime();
List<Integer> arrL = new LinkedList();
for(int i = 0; i < 5000000; ++i) {
arrL.add(i);
}
System.out.println( (System.nanoTime() - nano2) );
for(int j : arrL) {
;
}
System.out.println( (System.nanoTime() - nano2) );
【问题讨论】:
-
对于你的 LL,你是加头还是加尾?
-
另外请记住,如果您知道 ArrayList 需要保存多少个元素,则可以为 ArrayList 指定
initialCapacity,这消除了O(n)最坏的情况。 -
@Andrew 好点;如果您对数组大小有一个合理的下限,这总是一个好主意。
-
您说的是“顺序插入”,但上面的基准和引用是关于.add,它是一个追加(例如插入,但总是在最后一个元素之后)。插入意味着“在任何地方插入”,在讨论数据结构的操作成本时完全不同。
标签: java data-structures collections arraylist linked-list