java基础集合类——LinkedList 源码略读
1.概覽
LinkedList是java的動(dòng)態(tài)數(shù)組另一種實(shí)現(xiàn)方式,底層是基于雙向鏈表,而不是數(shù)組。
public class LinkedList<E>extends AbstractSequentialList<E>implements List<E>, Deque<E>, Cloneable, java.io.SerializableLinkedList實(shí)現(xiàn)了動(dòng)態(tài)數(shù)組與雙向隊(duì)列兩個(gè)接口,提供了兩種方法集合,可以用來(lái)實(shí)現(xiàn)隊(duì)列、棧之類(lèi)的功能。
2. 成員變量
先來(lái)看成員變量
transient int size = 0;transient Node<E> first;transient Node<E> last;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;}}鏈表一般就是有個(gè)head的節(jié)點(diǎn)就能完成對(duì)應(yīng)的工作。LinkedList實(shí)現(xiàn)了雙向鏈表,除了head,還有一個(gè)last節(jié)點(diǎn)和一個(gè)size參數(shù),這主要是為了效率考慮,不然查詢(xún)一次長(zhǎng)度或者尾都得來(lái)一次全鏈路迭代,太慢了。Node內(nèi)部類(lèi)就不說(shuō)了,非常簡(jiǎn)單的一個(gè)節(jié)點(diǎn)類(lèi)。
3. 方法
3.1 構(gòu)造方法
public LinkedList() {// 此時(shí)first=last=null,size=0}public LinkedList(Collection<? extends E> c) {this();addAll(c);}3.2 添加元素
添加一個(gè)元素
public boolean add(E e) {linkLast(e);return true;}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;elsel.next = newNode;size++;modCount++;}很簡(jiǎn)單的添加邏輯,再來(lái)看一下addAll的實(shí)現(xiàn)
public boolean addAll(Collection<? extends E> c) {return addAll(size, c);}public boolean addAll(int index, Collection<? extends E> c) {checkPositionIndex(index);Object[] a = c.toArray();int numNew = a.length;if (numNew == 0)return false;Node<E> pred, succ;if (index == size) {succ = null;pred = last;} else {succ = node(index);pred = succ.prev;}for (Object o : a) {@SuppressWarnings("unchecked") E e = (E) o;Node<E> newNode = new Node<>(pred, e, null);if (pred == null)first = newNode;elsepred.next = newNode;pred = newNode;}if (succ == null) {last = pred;} else {pred.next = succ;succ.prev = pred;}size += numNew;modCount++;return true;}3.3 刪除元素
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;}3.4 修改元素
public E set(int index, E element) {checkElementIndex(index);Node<E> x = node(index);E oldVal = x.item;x.item = element;return oldVal;}3.5 檢索元素
public E get(int index) {checkElementIndex(index);return node(index).item;}Node<E> node(int index) {// assert isElementIndex(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;}}檢索是LinkedList比較值得看的一個(gè)方法,java的實(shí)現(xiàn)很簡(jiǎn)單,先判斷index是大于當(dāng)前size的一半還是小于,如果是大于則從尾節(jié)點(diǎn)往前否則從首結(jié)點(diǎn)往后檢索。從代碼上看,雖然雙向鏈表的實(shí)現(xiàn)讓性能快了一點(diǎn),但還是O(n)的耗時(shí),我覺(jué)得后續(xù)版本的優(yōu)化可以向HashMap那樣,當(dāng)判斷LinkedList的size大于一個(gè)閾值時(shí)可以將雙向鏈接改造為紅黑樹(shù)或者跳表,從而實(shí)現(xiàn)O(lgn)的性能,當(dāng)然這樣也對(duì)空間消耗更多一點(diǎn)。
3.6 清空元素
public void clear() {// Clearing all of the links between nodes is "unnecessary", but:// - helps a generational GC if the discarded nodes inhabit// more than one generation// - is sure to free memory even if there is a reachable Iteratorfor (Node<E> x = first; x != null; ) {Node<E> next = x.next;x.item = null;x.next = null;x.prev = null;x = next;}first = last = null;size = 0;modCount++;}從代碼上看,LinkedList的clear方法是沒(méi)有內(nèi)存泄漏問(wèn)題的,注意有個(gè)for循環(huán),這里是為了gc優(yōu)化。
轉(zhuǎn)載于:https://www.cnblogs.com/oreo/p/10829004.html
總結(jié)
以上是生活随笔為你收集整理的java基础集合类——LinkedList 源码略读的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: app推送以及提示音java,sprin
- 下一篇: vim中跳到第一行和最后一行