LinkedList解析,與ArrayList優(yōu)劣對比

基于JDK1.8
只列出關(guān)鍵方法,關(guān)注初始化、add、get、remove

public LinkedList() { //默認(rèn)沒做任何操作
}
public boolean add(E e) {
    linkLast(e);
    return true;
}

transient Node<E> first;
transient Node<E> last;

void linkLast(E e) {
    final Node<E> l = last;
    final Node<E> newNode = new Node<>(l, e, null);
    last = newNode;
    if (l == null)
        first = newNode;
    else
        l.next = newNode;
    size++; //size()方法返回值
    modCount++;
}
private static class Node<E> {
    E item;
    Node<E> next;
    Node<E> prev;

    Node(Node<E> prev, E element, Node<E> next) {
        this.item = element;
        this.next = next;
        this.prev = prev;
    }
}

能看出來是這樣的結(jié)構(gòu):

first {pre=null; next = e1; item="a"}
e1 {pre=first; next=e2; item="b"}
e2 {pre=e1; next=e3; item="c"}
...
last {pre=en; next=null; item="x"}

看看get()實現(xiàn)

public E get(int index) {
    checkElementIndex(index);
    return node(index).item;
}
Node<E> node(int index) {
    if (index < (size >> 1)) {
        Node<E> x = first;
        for (int i = 0; i < index; i++)
            x = x.next;
        return x;
    } else {
        Node<E> x = last;
        for (int i = size - 1; i > index; i--)
            x = x.prev;
        return x;
    }
}

如果index<size/2,則從頭部往后查找,反之則從尾部往前查找。

再看remove()實現(xiàn)

public E remove(int index) {
    checkElementIndex(index);
    return unlink(node(index));
}
E unlink(Node<E> x) {
    // assert x != null;
    final E element = x.item;
    final Node<E> next = x.next;
    final Node<E> prev = x.prev;
    if (prev == null) {
        first = next;
    } else {
        prev.next = next;
        x.prev = null;
    }
    if (next == null) {
        last = prev;
    } else {
        next.prev = prev;
        x.next = null;
    }
    x.item = null;
    size--;
    modCount++;
    return element;
}

先找到index的Node,找到后做的事情也比較簡單,比如原本是

first {pre=null; next = e1; item="a"}
e1 {pre=first; next=e2; item="b"}
e2 {pre=e1; next=e3; item="c"}
...
last {pre=en; next=null; item="x"}

remove(1)后

first {pre=null; next = e2; item="a"}
e2 {pre=first; next=e3; item="c"}
...
last {pre=en; next=null; item="x"}

與ArrayList對比

對于get()和set(),ArrayList優(yōu)于LinkedList,因為LinkedList要遍歷查找(最壞情況遍歷次數(shù)=size/2),而數(shù)組可以直接定位。
對于add(index,element),ArrayList需要操作index后面的所有節(jié)點(diǎn)往后挪一個位,LinkedList只需修改前后2個node的指向,如果index不是最后一位,那么LinkedList效率更高,如果index是最后一位,實測還是ArrayList效率更高。

ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < 1000000; i++) {
    list.add(i);
} //耗時105ms
LinkedList<Integer> list = new LinkedList<>();
for (int i = 0; i < 1000000; i++) {
    list.add(i);
} //耗時220ms

對于remove(index),ArrayList需要把index后面的值都往前挪一個位,LinkedList則需要遍歷查找到該index所在的node。

for (int i = 0; i < 10000; i++) {
    list.remove(i);
}

從第一位開始remove,ArrayList耗時4680ms,LinkedList耗時513ms
從末尾開始remove,ArrayList耗時4722ms,LinkedList耗時305ms

總結(jié)

get(index)、set(index, element) ArrayList絕對優(yōu)勢
add(element) ArrayList略勝一籌
add(index, element) index越小,ArrayList效率越低,平均來算LinkedList優(yōu)勢
remove() LinkedList絕對優(yōu)勢

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容