您的位置:首页 > 其它

List之LinkedList源码分析

2016-02-19 16:14 399 查看
public class LinkedList<E>

extends AbstractSequentialList<E>

implements List<E>, Deque<E>, Cloneable, java.io.Serializable

源码版本为JDK1.7.0_75.

LinkedList继承了类AbstractSequentialList的双向链表,可以被当作堆栈、队列或双端队列进行操作。

LinkedList实现了List接口,可被当作队列操作;实现了Deque接口,可被当作双端队列操作;实现了Cloneable接口,说明可被克隆;实现了java.io.Serializable接口,说明它支持序列化。LinkedList是非同步的。

在网上找到的LinkedList源码分析好像大部分都是JDK1.6,其LinkedList使用的是循环双向链表,只有一个header,header结点不保存数据,而1.7版本改成非循环双向链表,分别使用first和last指向队首、队尾,这样对于在队首、队尾添加或删除等操作都只要O(1)的时间。

成员变量

transient int size = 0;

/**

* 指向头部的指针

* Pointer to first node.

* Invariant: (first == null && last == null) ||

* (first.prev == null && first.item != null)

*/

transient Node<E> first;

/**

* 指向尾部的指针

* Pointer to last node.

* Invariant: (first == null && last == null) ||

* (last.next == null && last.item != null)

*/

transient Node<E> last;

其中,Node类为LinkedList内部静态类

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;

}

}

构造函数

一个是构造空队列;另一个是将Collection集合数据添加到队列中。

/**

* Constructs an empty list.

*/

public LinkedList() {

}

/**

* Constructs a list containing the elements of the specified

* collection, in the order they are returned by the collection's

* iterator.

*

* @param c the collection whose elements are to be placed into this list

* @throws NullPointerException if the specified collection is null

*/

public LinkedList(Collection<? extends E> c) {

this();

addAll(c);

}

方法:

linkFirst、linkLast、linkBefore、unLinkBefore、unLinkLast、unLink这些方法主要是为add、remove等public方法服务。

/**

* 将元素e添加到头部,首先创建节点保存元素e,然后将该节点的next指向first,若first不为空,则将first的prev指向该节点;若first为空,则修改last指向该节点。

* Links e as first element.

*/

private void linkFirst(E e) {

final Node<E> f = first;

final Node<E> newNode = new Node<>(null, e, f);

first = newNode;

if (f == null)

last = newNode;

else

f.prev = newNode;

size++;

modCount++;

}

/**

* 将元素e插入到尾部。首先创建节点保存元素e,若last不为空,则将该节点的prev指向last,否则修改first指向该节点。

* Links e as last element.

*/

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++;

modCount++;

}

/**

* 将元素e插入到非空节点succ之前。

* Inserts element e before non-null Node succ.

*/

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;

else

pred.next = newNode;

size++;

modCount++;

}

/**

* 删除非空头节点f。修改first,注意要将头节点的成员变量都设置为null,使得该节点被GC回收

* Unlinks non-null first node f.

*/

private E unlinkFirst(Node<E> f) {

// assert f == first && f != null;

final E element = f.item;

final Node<E> next = f.next;

f.item = null;

f.next = null; // help GC

first = next;

if (next == null)

last = null;

else

next.prev = null;

size--;

modCount++;

return element;

}

/**

* 删除最后一个非空节点。修改last。

* Unlinks non-null last node l.

*/

private E unlinkLast(Node<E> l) {

// assert l == last && l != null;

final E element = l.item;

final Node<E> prev = l.prev;

l.item = null;

l.prev = null; // help GC

last = prev;

if (prev == null)

first = null;

else

prev.next = null;

size--;

modCount++;

return element;

}

/**

* 删除链表中非空节点x。

* Unlinks non-null node x.

*/

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;

}

// Positional Access Operation 位置访问操作

根据下表index查找并返回结点,方法get、set、add、remove主要利用该方法实现。它根据index是否大于size/2来确定是从头遍历还是从尾遍历。

/**

* Returns the (non-null) Node at the specified element index.

*/

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;

}

}

// Search Operations 搜索操作

indexOf和lastIndexOf也是遍历链表查找。

// Queue Operations 队列操作

/**

* 返回队首元素,但不删除队首,若不存在,返回null

* Retrieves, but does not remove, the head (first element) of this list.

*

* @return the head of this list, or {@code null} if this list is empty

* @since 1.5

*/

public E peek() {

final Node<E> f = first;

return (f == null) ? null : f.item;

}

/**

* 返回队首元素,但不删除,若不存在,抛出异常

* Retrieves, but does not remove, the head (first element) of this list.

*

* @return the head of this list

* @throws NoSuchElementException if this list is empty

* @since 1.5

*/

public E element() {

return getFirst();

}

/**

* 返回并删除队首元素,若为空,返回null

* Retrieves and removes the head (first element) of this list.

*

* @return the head of this list, or {@code null} if this list is empty

* @since 1.5

*/

public E poll() {

final Node<E> f = first;

return (f == null) ? null : unlinkFirst(f);

}

/**

* 返回并删除队首元素,若为空,抛出异常

* Retrieves and removes the head (first element) of this list.

*

* @return the head of this list

* @throws NoSuchElementException if this list is empty

* @since 1.5

*/

public E remove() {

return removeFirst();

}

/**

* 将特定元素添加到队尾

* Adds the specified element as the tail (last element) of this list.

*

* @param e the element to add

* @return {@code true} (as specified by {@link Queue#offer})

* @since 1.5

*/

public boolean offer(E e) {

return add(e);

}

// Deque operations 双端队列操作

/**

* 将特定元素插入到队首

* Inserts the specified element at the front of this list.

*

* @param e the element to insert

* @return {@code true} (as specified by {@link Deque#offerFirst})

* @since 1.6

*/

public boolean offerFirst(E e) {

addFirst(e);

return true;

}

/**

* 将特定元素插入到队尾

* Inserts the specified element at the end of this list.

*

* @param e the element to insert

* @return {@code true} (as specified by {@link Deque#offerLast})

* @since 1.6

*/

public boolean offerLast(E e) {

addLast(e);

return true;

}

/**

* 返回但不删除队列第一个元素,若为空,则返回null

* Retrieves, but does not remove, the first element of this list,

* or returns {@code null} if this list is empty.

*

* @return the first element of this list, or {@code null}

* if this list is empty

* @since 1.6

*/

public E peekFirst() {

final Node<E> f = first;

return (f == null) ? null : f.item;

}

/**

* 返回但不删除队列最后一个元素,若为空,则返回null

* Retrieves, but does not remove, the last element of this list,

* or returns {@code null} if this list is empty.

*

* @return the last element of this list, or {@code null}

* if this list is empty

* @since 1.6

*/

public E peekLast() {

final Node<E> l = last;

return (l == null) ? null : l.item;

}

/**

* 返回并删除队列第一个元素,若为空,则返回null

* Retrieves and removes the first element of this list,

* or returns {@code null} if this list is empty.

*

* @return the first element of this list, or {@code null} if

* this list is empty

* @since 1.6

*/

public E pollFirst() {

final Node<E> f = first;

return (f == null) ? null : unlinkFirst(f);

}

/**

* 返回并删除队列最后一个元素,若为空,则返回null

* Retrieves and removes the last element of this list,

* or returns {@code null} if this list is empty.

*

* @return the last element of this list, or {@code null} if

* this list is empty

* @since 1.6

*/

public E pollLast() {

final Node<E> l = last;

return (l == null) ? null : unlinkLast(l);

}

/**

* Pushes an element onto the stack represented by this list. In other

* words, inserts the element at the front of this list.

*

* <p>This method is equivalent to {@link #addFirst}.

*

* @param e the element to push

* @since 1.6

*/

public void push(E e) {

addFirst(e);

}

/**

* Pops an element from the stack represented by this list. In other

* words, removes and returns the first element of this list.

*

* <p>This method is equivalent to {@link #removeFirst()}.

*

* @return the element at the front of this list (which is the top

* of the stack represented by this list)

* @throws NoSuchElementException if this list is empty

* @since 1.6

*/

public E pop() {

return removeFirst();

}

/**

* Removes the first occurrence of the specified element in this

* list (when traversing the list from head to tail). If the list

* does not contain the element, it is unchanged.

*

* @param o element to be removed from this list, if present

* @return {@code true} if the list contained the specified element

* @since 1.6

*/

public boolean removeFirstOccurrence(Object o) {

return remove(o);

}

/**

* Removes the last occurrence of the specified element in this

* list (when traversing the list from head to tail). If the list

* does not contain the element, it is unchanged.

*

* @param o element to be removed from this list, if present

* @return {@code true} if the list contained the specified element

* @since 1.6

*/

public boolean removeLastOccurrence(Object o) {

if (o == null) {

for (Node<E> x = last; x != null; x = x.prev) {

if (x.item == null) {

unlink(x);

return true;

}

}

} else {

for (Node<E> x = last; x != null; x = x.prev) {

if (o.equals(x.item)) {

unlink(x);

return true;

}

}

}

return false;

}

clone方法首先调用superClone方法(该方法调用父类clone方法)得到链表,然后遍历原始链表将节点添加新链表中。该方法属于浅拷贝。

@SuppressWarnings("unchecked")

private LinkedList<E> superClone() {

try {

return (LinkedList<E>) super.clone();

} catch (CloneNotSupportedException e) {

throw new InternalError();

}

}

/**

* Returns a shallow copy of this {@code LinkedList}. (The elements

* themselves are not cloned.)

*

* @return a shallow copy of this {@code LinkedList} instance

*/

public Object clone() {

LinkedList<E> clone = superClone();

// Put clone into "virgin" state

clone.first = clone.last = null;

clone.size = 0;

clone.modCount = 0;

// Initialize clone with our elements

for (Node<E> x = first; x != null; x = x.next)

clone.add(x.item);

return clone;

}

参考:

/article/5049987.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: