我在此之前的一篇帖子中写道:
对于LinkedList
- 得到的是O(n)
- 加为O(1)
- 删除为O(n)
- Iterator.remove为O(1)
对于ArrayList
- 得到的是O(1)
- add为O(1)摊销,但O(n)为最差情况,因为必须调整数组大小并复制
- 删除为O(n)
因此,通过查看此内容,我得出的结论是,如果只对我的集合中的序列插入(比如说5000000个元素),LinkedList
它将超出类别ArrayList
。
而且,如果我只需要通过迭代来从集合中获取元素,即不从中间抓取元素,那么它仍然LinkedList
会比ArrayList更好。
现在,要验证我的上述两个语句,我编写了以下示例程序…但令我惊讶的是,我的上述语句被证明是错误的。
ArrayList``Linkedlist
在这两种情况下都超过了。LinkedList
与从Collection中进行添加和获取相比,花费的时间更少。有什么我做错了,或有关初步陈述LinkedList
和ArrayList
尺寸为500万的收藏品不成立?
我提到过大小,因为如果将元素数量减少到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) );
请记住,big-
O复杂性描述的是渐近行为,可能无法反映实际的实现速度。它描述了每个操作的成本如何随列表的大小而增加,而不是每个操作的速度。例如,下面的实现add
是O(1),但速度不快:
public class MyList extends LinkedList {
public void add(Object o) {
Thread.sleep(10000);
super.add(o);
}
}
我怀疑在您的情况下ArrayList表现良好,因为它相当大地增加了其内部缓冲区的大小,因此不会有大量的重新分配。当不需要调整缓冲区大小时,ArrayList将具有更快的add
s。
在进行此类分析时,还需要非常小心。我建议您更改配置文件代码以进行预热阶段(这样,JIT就有机会进行一些优化而不影响您的结果),并在多次运行中平均结果。
private final static int WARMUP = 1000;
private final static int TEST = 1000;
private final static int SIZE = 500000;
public void perfTest() {
// Warmup
for (int i = 0; i < WARMUP; ++i) {
buildArrayList();
}
// Test
long sum = 0;
for (int i = 0; i < TEST; ++i) {
sum += buildArrayList();
}
System.out.println("Average time to build array list: " + (sum / TEST));
}
public long buildArrayList() {
long start = System.nanoTime();
ArrayList a = new ArrayList();
for (int i = 0; i < SIZE; ++i) {
a.add(i);
}
long end = System.nanoTime();
return end - start;
}
... same for buildLinkedList
(请注意,sum
可能会溢出,因此最好使用System.currentTimeMillis()
)。
编译器也有可能正在优化空get
循环。确保循环实际上执行了某些操作,以确保调用正确的代码。
问题内容: 因此,我有一个自定义班级班级,该班级将有一组其他自定义班级的学生。因此它将看起来像这样: 现在,我将向集合中的学生添加和删除许多学生,并且还将改变已经在集合中的学生的许多私有字段。 问题:应该使用哪种数据结构来最好地实现此目的?由于我将更改set Student中Student对象的属性(从而更改哈希码),因此我应该改用ArrayList吗? 问题答案: 我应该使用哪种数据结构来最好地
本文向大家介绍Arraylist 与 LinkedList 区别?相关面试题,主要包含被问及Arraylist 与 LinkedList 区别?时的应答技巧和注意事项,需要的朋友参考一下 数据结构实现:ArrayList 是动态数组的数据结构实现,而 LinkedList 是双向链表的数据结构实现。 随机访问效率:ArrayList 比 LinkedList 在随机访问的时候效率要高,因为 Lin
问题内容: 为何以上行失败: 无法实例化类型 但这一项有效: 问题答案: 正确的方法是: 通过其接口()引用对象 使用其具体类型()实例化对象(无法实例化接口)
问题内容: 创建String 的最佳构造是什么?是(来自番石榴)还是? 只是个人喜好吗? 还是仅仅是Type泛型类型推断? 还是使用Lists.newArrayList()有任何理论或实践价值? 问题答案: 番石榴构建器保存多次键入type参数。比较: 但是在Java 7中,它已经过时了,因为您拥有菱形运算符:
问题内容: 作为C ++老朋友,我设法解决了我的问题,但是我无法在这里围绕底层的Java机制: 问题答案: 是一个接口,有点像带有C ++中某些方法的类。您无法实例化它。 但是“继承” (或用Java术语实现),因此这些引用是分配兼容的。
问题内容: 向量是同步的,ArrayList是不同步的,但是我们可以通过来同步ArrayList ,那么哪个会更好,更快地执行? 问题答案: 同步收集既浪费时间又危险。一个很简单的例子,为什么它们不好,是考虑两个线程在同一集合上同时运行一个循环: 我们的列表可能是同步的(例如,Vector),并且此代码仍然可怕地中断。为什么?因为对size(),get(),remove()的单个调用是同步的,但是