ArrayList跟linkList

bluetooth發表於2021-09-09

 public class LinkedListextends AbstractSequentialListimplements List, Deque, Cloneable, java.io.SerializableLinkedList 是⼀一個繼承於AbstractSequentialList的雙向連結串列。它也可以被當作堆疊、佇列列或雙端佇列列進⾏行行操作。LinkedList 實現List接⼝口,能對它進⾏行行佇列列操作。LinkedList 實現Deque接⼝口,雙向佇列列,它⽀支援從兩個端點⽅方向檢索和插⼊入元素。LinkedList 實現了了Cloneable接⼝口,即覆蓋了了函式clone(),能克隆隆。LinkedList 實現java.io.Serializable接⼝口,這意味著LinkedList⽀支援序列列化,能透過序列列化去傳輸。關鍵字transient 標識的欄位的⽣生命週期僅存於調⽤用者的記憶體中⽽而不不會寫到磁碟⾥裡里持久化 transient int size = 0;transient Node first;transient Node last;LinkedList 每個儲存元素是⼀一個Node物件LinkedList 原始碼分析LinkedList 繼承結構開始分析LinkedList 屬性 private static class Node { E item; Node next; Node prev; Node(Node prev, E element, Node next) { this.item = element; this.next = next; this.prev = prev; }}在這個物件可以分析出.LinkedList 儲存開銷⽐比Arraylist ⼤大,因為LinkedList每個元素在記憶體⾥裡里多分配了了Nodenext; , Node prev; 兩個變數量值.得出.ArrayList 和 LinkedList 儲存相同⼤大⼩小的資料. LinkedList 佔記憶體⽐比較⼤大.  public LinkedList(Collection c) { this(); addAll(c); }從 return addAll(size, c);開始分析.引數1.新增位置 , 引數2,需要新增的資料;public boolean addAll(int index, Collection c) { checkPositionIndex(index);  Object[] a = c.toArray(); int numNew = a.length; if (numNew == 0) return false; // 上部分校驗資料是否為0 // 但是少了了空指標校驗.不不知道是不不是.挖了了坑給我們跳 -------------------------->  Node pred, succ; if (index == size) { //儲存index處的節點。插⼊入位置如果是size,則在頭結點前⾯面插⼊入,否則在獲取index 處的節點插⼊入 succ = null; pred = last; } else { //獲取前⼀一個節點,插⼊入時需要修改這個節點的next引⽤用succ = node(index);LinkedList 構造⽅方法 pred = succ.prev; } //可以理理解node擺放的位置 ----------------------------> for (Object o : a) { //在強制型別轉換的時候編譯器器會給出警告 //@SuppressWarnings("unchecked")此註解去除警告. @SuppressWarnings("unchecked") E e = (E) o; //建立node 引數1.node頭 ,引數2.資料 ,引數3.node尾 Node newNode = new Node(pred, e, null); if (pred == null) first = newNode; else //修改前⼀一節點的next指標 pred.next = newNode; pred = newNode; }  //收尾的處理理 if (succ == null) { last = pred; } else { pred.next = succ; succ.prev = pred; }  size += numNew; modCount++; return true;}LinkedList 初始化操作會處理理⼀一⼤大坨的.頭--尾.地址轉換.ArrayList 初始化操作會不不斷的copy陣列.為了了⾃自增Arrays.copyOf(elementData, size, Object[].class);LinkedList 新增元素  public void add(int index, E element) { checkPositionIndex(index); if (index == size) linkLast(element); else linkBefore(element, node(index));}擦屁股 void linkLast(E e) { final Node l = last; final Node newNode = new Node(l, e, null); last = newNode;  if (l == null) first = newNode; else l.next = newNode; size++; modCount++; }按指定位置插  void linkBefore(E e, Node succ) { final Node pred = succ.prev; final Node newNode = new Node(pred, e, succ); succ.prev = newNode; if (pred == null) first = newNode; else pred.next = newNode; size++; modCount++;}LinkedList 新增⼜又是處理理頭--尾.地址轉換ArrayList 新增⼜又會copy陣列.為了了⾃自增linkLast ⽅方法linkBefore ⽅方法//Arraylist ⾃自增⻓長 private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1);  if (newCapacity - minCapacity 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: --------------------------- elementData = Arrays.copyOf(elementData, newCapacity); ---------------------------}public boolean remove(Object o) { if (o == null) { //刪除第⼀一個空的元素.、 for (Node x = first; x != null; x = x.next) { if (x.item == null) { unlink(x); return true; } } } else { //查詢元素並.刪除 for (Node x = first; x != null; x = x.next) { //注意.如果obj.equals(obj)最好重寫equals 和 hashCode ⽅方法 if (o.equals(x.item)) { unlink(x); return true; } } } return false;}刪除節點把節點的.所有屬性指nullLinkedList 刪除元素unlink ⽅方法E unlink(Node x) { final E element = x.item; final Node next = x.next; final Node 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;}LinkedList 刪除元素.先把⾃自⼰己的東⻄西給別⼈人.然後⾃自⼰己指空.ArrayList 刪除元素.還是操作 Copy 陣列 public E remove(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); modCount++; E oldValue = (E) elementData[index]; int numMoved = size - index - 1; if (numMoved > 0) //********** //引數1.源陣列 //引數2.複製的起始位置 //引數3.⽬目標陣列 //引數4.⽬目標陣列的位置 //引數5.源陣列需要複製的⻓長度 System.arraycopy(elementData, index+1, elementData, index, numMoved); //*********** elementData[--size] = null; // clear to let GC do its work return oldValue;}public E get(int index) { checkElementIndex(index); return node(index).item;}LinkedList 獲取元素node ⽅方法 Node node(int index) { // 獲取index處的節點。 // 若index > 1)) { Node x = first; for (int i = 0; i x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x; }}LinkedList 獲取元素.需要⽤用迴圈找ArrayList 獲取元素直接index 下標查詢//ArrayList 獲取元素public E get(int index) { if (index = this.size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); if (ArrayList.this.modCount != this.modCount) throw new ConcurrentModificationException(); return (E) ArrayList.this.elementData[offset + index]; } 

原文連結:http://www.apkbus.com/blog-340477-76470.html

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3402/viewspace-2813199/,如需轉載,請註明出處,否則將追究法律責任。

相關文章