好吧,有很多关于LinkedList和ArrayList的讨论,但是当我在“Thinking in Java”中看到这个描述时,我仍感到困惑:
LinkedList也实现了像ArrayList那样的基本List接口,但它 执行某些操作(在列表中间插入和删除)更多 比ArrayList更有效率。
我不知道它为什么强调“在List的中间”,我认为当插入List的开头时,ArrayList还需要传递后面的元素,它比LinkedList快吗?
答案 0 :(得分:2)
以前的答案非常好,但是这些帮助我想象发生了什么,当我需要更详细的解释时:
<强>删除强>
和
<强>插入强>
答案 1 :(得分:1)
ArrayList
由数组支持,而LinkedList
由2个引用支持next
和previous
,即由DoublyLinkedList
支持{1}})。 LinkedList
更快,因为一旦调用add(int index,E element),它就不需要复制数组并将元素向右移动一个单元格。
当插入中间(或索引0和currentSize之间的任何位置)时,ArrayList
复制/移位元素,因此需要更多时间。而LinkedList
只需更改2个指针/引用。
ArrayList.java:
public void add(int index, E element) {
..
// copying elements
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
..
}
<强> LinkedList.java 强>
public void add(int index, E element) {
addBefore(element, (index==size ? header : entry(index)));
}
private Entry<E> addBefore(E e, Entry<E> entry) {
Entry<E> newEntry = new Entry<E>(e, entry, entry.previous);
// just changing the pointers
newEntry.previous.next = newEntry;
newEntry.next.previous = newEntry;
size++;
modCount++;
return newEntry;
}
答案 2 :(得分:1)
重点是暗示这样一个事实,即ArrayList内部需要移动元素,并保持开放内存以进行进一步插入,从而导致它移位和复制元素。 LinkedList将简单地创建一个节点,然后将前一节点的next
节点设置为新节点,并将新节点的next
节点设置为列表中的下一个节点。
还应该注意的是,虽然经典的LinkedList在中间的插入方面表现优异,但有时候ArrayList也会表现得更好,或者比LinkedList更好(这在多种语言之间通常很常见,包括C ++ [Bjarne Stroustrup实际上有一个关于这个概念的讲座])。你应该仔细考虑你正在做什么,并使用基准做出正确的决定。