1.從底層數據結構,擴容策略
2.LinkedList的增刪改查
3.特殊處理重點關注
4.遍歷的速度,隨機訪問和iterator訪問效率對比java
構造函數不作任何操做,只要再add的時候進行數據初始化操做,以操做推進邏輯,並且linkedlist是一個雙向鏈表,因此能夠向前向後雙向遍歷
因爲構造函數並無任何操做,其實這裏咱們能夠先看新增操做,而且由於用的是鏈表因此沒法隨機訪問,這裏隨機讀取就會比較慢node
安全
底層結構就是size,首節點,尾節點,還有就是一個List都有的共性就是modCount,這值用來記錄這個list被修改了多少次數據結構
Add操做的實質就是進行linklast操做多線程
linklast的操做就是再最後吧節點添加到尾部,並修正size大小函數
public boolean add(E ele) { linkLast(ele); return true; }
咱們看看若是是在指定的位置插入元素的操做
首先要確認index再指定範圍內
這裏有個小優化,若是是在末尾進行添加的話,咱們直接調用linklast就能夠了
若是不是最後一個,那麼首先要獲取指定位置的node節點,咱們遍歷指定位置的時候
能夠肯定index的位置若是過半了,那麼就從後往前,若是沒有過半,那麼就從前日後
1.直接再index建立一個節點,而後先後合併一下
2.吧原來的index位置的節點斷開,吧這個節點的pre指向新節點
3.判斷前置節點是否到頭了,爲空
4.把前置節點的next指向新節點學習
先看看node定位操做優化
而後咱們看看linkbefore,前置插入spa
public void linkBefore(E e, Node<E> succ) { final Node<E> pred = succ.prev; final Node<E> newNode = new Node<>(pred, e, succ); succ.prev = newNode; if (pred == null) first = newNode; else pred.next = newNode; size++; modCount++; }
那麼咱們須要插入到指定的位置的方法就能夠很簡單的實現了
Linkbefore(e, node(index))便可.net
查看源碼,比較remove(),remove(object),remove(index)等等操做,歸根到底仍是一個unlink操做
咱們須要對指定的節點進行unlink操做
就2步操做
1.當前節點的前一個節點指向當前節點的下一個節點,說白了node.pre.next = node.next;
2.當前節點的下一個節點的前置節點指向當前節點的上一個節點:node.next.pre = node.pre;
其餘細節部分就是首尾節點的處理
public E unlink(Node<E> node) { // assert x != null; //這裏須要操做的就是三個節點,前置節點,當前節點,後置節點 final E element = node.item; final Node<E> prev = node.prev; final Node<E> next = node.next; //當前節點的前一個節點指向當前節點的下一個節點,說白了node.pre.next = node.next; if (prev == null) { //避免首節點操做 first = next; } else { prev.next = next; node.prev = null; //斷開原始鏈接 } //當前節點的下一個節點的前置節點指向當前節點的上一個節點:node.next.pre = node.pre; if (next == null) { last = prev; } else { next.prev = prev; node.next = null; } //清除當前節點 node.item = null; size--; modCount++; return element; }
其他操做基本就是調用unlink方法進行操做
修改set和獲取get就很少說了,就注意一點就是set操做的時候,會返回舊值,而且這兩個操做不會修改modCount值,也就是不會產生鏈表變更
對於iterator這個就很少說了,其實仍是調用上面的那些方法,遍歷也就是next和pre和循環遍歷沒差異
可是注意一點就是經過迭代器進行remove和add是能夠的,可是注意一點,若是使用迭代器進行remove或者add操做的經過,還使用了通常的remove和add那麼就會使迭代器失效
序列化這裏咱們先只作一個瞭解,後續開章節專門學習一下java的序列化:
進行序列化、反序列化時,虛擬機會首先試圖調用對象裏的writeObject和readObject方法,進行用戶自定義的序列化和反序列化。若是沒有這樣的方法,那麼默認調用的是ObjectOutputStream的defaultWriteObject以及ObjectInputStream的defaultReadObject方法。換言之,利用自定義的writeObject方法和readObject方法,用戶能夠本身控制序列化和反序列化的過程。
---------------------
版權聲明:本文爲CSDN博主「zthgreat」的原創文章,遵循CC 4.0 by-sa版權協議,轉載請附上原文出處連接及本聲明。
原文連接:https://blog.csdn.net/u014634338/article/details/78165127
這個問題其實也能夠捨棄掉了,這裏遍歷的實質仍是使用鏈表的遍歷方式進行遍歷
LinkedList 是線程不安全的,容許元素爲null的雙向鏈表。
參考:https://blog.csdn.net/u014634338/article/details/78165127