我认为链接列表在添加元素时应该比arraylist更快?我刚刚测试了添加,排序和搜索元素所需的时间(arraylist vs linkedlist vs hashset)。我只是使用java.util类进行arraylist和linkedlist ...使用每个类可用的add(object)方法。
arraylist out在填写列表时执行了链表...并且在列表的线性搜索中。
这是对的吗?我在实施中做错了吗?
的 的 ** * ** * ** * 的** * *** 修改的 * ** * ** * ** * ** * ** * *
我只是想确保我正确使用这些东西。这就是我正在做的事情:
public class LinkedListTest {
private List<String> Names;
public LinkedListTest(){
Names = new LinkedList<String>();
}
然后我只使用链表列表方法,即“Names.add(strings)”。当我测试arraylists时,它几乎相同:
public class ArrayListTest {
private List<String> Names;
public ArrayListTest(){
Names = new ArrayList<String>();
}
我做得对吗?
答案 0 :(得分:11)
是的,没错。 LinkedList
必须在每次插入时进行内存分配,而ArrayList
允许执行更少的内存分配,并为其amortized O(1) insertion。内存分配看起来很便宜,但实际上可能非常昂贵。
由于引用的位置,LinkedList
的线性搜索时间可能较慢:ArrayList
元素更靠近,因此cache misses更少。
当您计划仅在List
的末尾插入时,ArrayList
是实施选择。
答案 1 :(得分:3)
请记住:
因此,例如,链接列表在添加到结尾时还有更多工作要做,因为它有一个额外的对象来分配和初始化每个项目添加,但无论每个项目的“内在”成本如何,两个结构都将具有O (1)添加到列表末尾的性能,即无论列表的大小如何,每次添加都有一个有效的“常量”时间,但是ArrayList与LinkedList之间的常量会有所不同,后者可能会更大。 / p>
另一方面,链表有恒定的时间添加到列表的开头,而在ArrayList的情况下,元素必须“shuftied”,这个操作花费一些时间与数字成比例元素。但是,对于给定的列表大小,比如100个元素,“shufty”100个元素可能比分配和初始化链表的单个占位符对象更快(但是当你到达时,比如,一千或一百万个物体或任何阈值,它不会是。)
因此,在您的测试中,您可能想要考虑给定大小的操作的“原始”时间以及这些操作扩展随着列表大小的增长。
答案 2 :(得分:1)
当将一个元素添加到LinkedList的后面时(在Java LinkedList中实际上是一个双向链表),它是一个O(1)
操作,就像在它前面添加一个元素一样。在i
位置添加元素大致是O(i)
操作。
因此,如果您要添加到列表的前面,则LinkedList会明显更快。
答案 3 :(得分:1)
为什么你认为LinkedList
会更快?在一般情况下,插入数组列表只是更新单个数组单元的指针(使用O(1)随机访问)的情况。 LinkedList插入也是随机访问,但必须分配一个“单元”对象来保存条目,并更新一对指针,以及最终设置对正在插入的对象的引用。
当然,可能需要定期调整ArrayList的后备阵列(如果选择初始容量足够大,则不会出现这种情况),但由于阵列呈指数级增长,因此摊销成本会很低,并且受O(lg n)
复杂性限制。
简单地说 - 插入数组列表要简单得多,因此总体来说要快得多。
答案 4 :(得分:1)
在这些情况下,链接列表可能比数组列表慢,原因有几个。如果要插入列表的末尾,则阵列列表可能已经分配了此空间。底层数组通常以大块的形式增加,因为这是一个非常耗时的过程。因此,在大多数情况下,在后面添加元素只需要粘贴在引用中,而链表需要创建节点。在前面和中间添加应该为两种类型的列表提供不同的性能。
列表的线性遍历在基于数组的列表中总是更快,因为它必须只能正常遍历数组。这需要每个单元一次解除引用操作。在链表中,列表中的节点也必须被解除引用,占用的时间加倍。
答案 5 :(得分:0)
ArrayList访问随机索引数据的速度更快,但在列表中间插入元素时速度较慢,因为使用链表只需更改参考值。但是在数组列表中,你必须在插入的索引之后复制所有元素,后面有一个索引。
编辑:是不是有一个链表实现,它记住了最后一个元素?这样做会加快使用链表的插入速度。