LinkedList源码学习
生活随笔
收集整理的這篇文章主要介紹了
LinkedList源码学习
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?
鏈表數據結構
當前節點會保存上一個、下一個節點。 參見 LinkedList的Node類
實現:
1. 內部鏈表的方式。
1.1 添加元素。追加的方式,創建一個新的節點[Node],用最后一個節點關聯新的節點。
1.2 刪除元素
1.2.1 通過對象刪除。遍歷鏈表,刪除第一個匹配的對象
??修改鏈表關聯結構
2. 內部是同步[modCount]
2.1 LinkedList數據結構變化的時候,都會將modCount++。
2.2 采用Iterator遍歷的元素, next()會去檢查集合是否被修改[checkForComodification],如果集合變更會拋出異常
類似于數據庫層面的 樂觀鎖 機制。 可以通過 Iterator的api去刪除元素
3. 數組結構,內部存儲數據是有序的,并且數據可以為null
?
源碼實現
package xin.rtime.collections.list;import java.util.ConcurrentModificationException; import java.util.Iterator; import java.util.ListIterator; import java.util.NoSuchElementException;// 鏈表的源碼實現 public class LinkedList<E> {transient int size = 0; // 當前鏈表的size transient Node<E> first; // 首節點 transient Node<E> last; // 尾節點private int modCount = 0; // 結構修改次數// 添加節點public boolean add(E e) {linkLast(e);return true;}// 刪除節點public boolean remove(Object o) {if (o == null) {for (Node<E> x = first; x != null; x = x.next) {if (x.item == null) {unlink(x);return true;}}} else {for (Node<E> x = first; x != null; x = x.next) {if (o.equals(x.item)) { // equals unlink(x);return true;}}}return false;}// 獲取節點public E get(int index) {checkElementIndex(index); // 檢查元素Index是否存在 , 不存在會拋出數組越界return node(index).item;}// 獲取鏈表sizepublic int size() {return size;}public Iterator<E> iterator() {return listIterator();}public ListIterator<E> listIterator() {return listIterator(0);}Node<E> node(int index) {// assert isElementIndex(index);if (index < (size >> 1)) { // 當前index 小于 當前一半容量的 sizeNode<E> x = first; // 當前節點 等于 首節點for (int i = 0; i < index; i++) // 遍歷 index -1 次x = x.next; // x 等于當前節點的下一個節點return x;} else { // 大于Node<E> x = last;for (int i = size - 1; i > index; i--) // 從尾部開始遍歷x = x.prev; // x 等于當前節點的上一個節點return x;}}private void checkElementIndex(int index) {if (!isElementIndex(index)) // 節點index是否在鏈表的容量范圍內throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}private boolean isElementIndex(int index) {return index >= 0 && index < size;}private String outOfBoundsMsg(int index) {return "Index: "+index+", Size: "+size;}// 獲得首個節點值public E getFirst() {final Node<E> f = first;if (f == null)throw new NoSuchElementException();return f.item;}// 獲得尾部節點值public E getLast() {final Node<E> l = last;if (l == null)throw new NoSuchElementException();return l.item;}// 獲得所有節點值public Object[] toArray() {Object[] result = new Object[size];int i = 0;for (Node<E> x = first; x != null; x = x.next)result[i++] = x.item;return result;}public ListIterator<E> listIterator(int index) {checkPositionIndex(index);return new ListItr(index);}private void checkPositionIndex(int index) {if (!isPositionIndex(index))throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}// 判斷當前節點index是否存在private boolean isPositionIndex(int index) {return index >= 0 && index <= size;}private class ListItr implements ListIterator<E> {private Node<E> lastReturned = null; // 返回的節點private Node<E> next; // 下個節點private int nextIndex; // 下個節點 下標private int expectedModCount = modCount; // 預期的修改次數 = 等于遍歷時的修改次數 ListItr(int index) {// assert isPositionIndex(index);next = (index == size) ? null : node(index);nextIndex = index;}public boolean hasNext() {return nextIndex < size;}public E next() {checkForComodification(); // 校驗當前鏈表是否被改動if (!hasNext())throw new NoSuchElementException();lastReturned = next;next = next.next;nextIndex++;return lastReturned.item;}public boolean hasPrevious() {return nextIndex > 0;}public E previous() {checkForComodification(); // 校驗當前鏈表是否被改動if (!hasPrevious())throw new NoSuchElementException();lastReturned = next = (next == null) ? last : next.prev;nextIndex--;return lastReturned.item;}public int nextIndex() {return nextIndex;}public int previousIndex() {return nextIndex - 1;}public void remove() {checkForComodification(); // 校驗當前鏈表是否被改動if (lastReturned == null)throw new IllegalStateException();Node<E> lastNext = lastReturned.next;unlink(lastReturned); // 剔除節點if (next == lastReturned)next = lastNext;elsenextIndex--;lastReturned = null;expectedModCount++;}// 當前節點設置值public void set(E e) {if (lastReturned == null)throw new IllegalStateException();checkForComodification();lastReturned.item = e; }public void add(E e) {checkForComodification();lastReturned = null;if (next == null) // 下一個節點為nulllinkLast(e); // 在尾部插入elselinkBefore(e, next); // 在指定節點之前插入nextIndex++;expectedModCount++;}final void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();}}private E unlink(Node<E> x) {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; // 當前節點的上一個節點置為null gc回收 }if (next == null) { // 下一個節點為空last = prev; // 最后節點 = 當前節點的上一個節點} else { // 不為空 next.prev = prev; // 上一個節點的上一個節點 等于 當前節點的上一個節點x.next = null; // 當前節點的下一個節點置為null gc回收 }x.item = null; // 當前元素置為null gc回收size--; // 長度 + 1modCount++; // 修改次數+1return element;}// 在鏈表的尾部插入節點void linkLast(E e) {final Node<E> l = last; // 最后一個元素final Node<E> newNode = new Node<>(l, e, null); // 上一個元素,當前元素,nulllast = newNode; // 最后一個節點等新建的節點if (l == null) // 如果最后一個節點為空first = newNode; // 出現一個情況: 當鏈表為空的時候 , first 和 last 都為 newNodeelsel.next = newNode; //最后節點的下一個節點,等于當前節點size++; // 鏈表長度+1modCount++; // 修改次數+1 }// 在指定節點添加上一個節點void linkBefore(E e, Node<E> succ) {// assert succ != null;final Node<E> pred = succ.prev;final Node<E> newNode = new Node<>(pred, e, succ);succ.prev = newNode;if (pred == null)first = newNode;elsepred.next = newNode;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;}} }?
轉載于:https://www.cnblogs.com/LuisYang/p/10034601.html
總結
以上是生活随笔為你收集整理的LinkedList源码学习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VMware设置及linux静态ip设置
- 下一篇: PyCherm的常用快捷键总结