参考博客:http://www.cnblogs.com/skywang12345/p/3561803.html,表示感谢!
LinkedList 是List接口的一个基于双向链表的实现类,继承了AbstractSequentialList类,实现了List接口,Queue接口(队列),Deque(双端队列),Cloneable接口,Serializable接口。因此LinkedList具有队列的特点,可以作为堆栈,队列,双端队列使用。
和ArrayList一样,LinkedList也是非同步的,如果不需要使用队列的特性的话,一般使用ArrayList。
遍历LinkedList时,使用removeFist()或removeLast()效率最高。但用它们遍历时,
会删除原始数据;若单纯只读取,而不删除,应该使用增强for循环或者iterator的方式,
千万不要使用角标访问的形式来遍历。
LinkedList与Collection关系如下图:
LinkedList的本质是一个双向链表,那么什么是双向链表呢?
双向链表(双链表)是链表的一种。双链表由一个个节点组成,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
双链表的示意图如下:
表头为空,表头的后继节点为"节点10"(数据为10的节点);"节点10"的后继节点是"节点20"(数据为10的节点),"节点20"的前继节点是"节点10";"节点20"的后继节点是"节点30","节点30"的前继节点是"节点20";...;末尾节点的后继节点是表头。
双链表删除节点
双链表添加节点
LinkedList源码分析:
package java.util;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Array;
/**
* @since 1.2
*/
public class LinkedList extends AbstractSequentialList implements
List, Deque, Queue, Cloneable, Serializable {
private static final long serialVersionUID = 876323262645176354L;
//LinkedList中的元素的数量
transient int size = 0;
//双链表中的head,它是空的,不保存数据
transient Link voidLink;
//LinkedList中的节点,用来保存数据,
//每个节点包含向前 向后的节点的引用以及本节点的数据
private static final class Link {
ET data;
Link previous, next;
Link(ET o, Link p, Link n) {
data = o;
previous = p;
next = n;
}
}
//LinkedList内部的iterator实现,可以用来进行遍历以及数据的增删修改
private static final class LinkIterator implements ListIterator {
int pos, expectedModCount;
final LinkedList list;
//当前节点 最后节点的引用
Link link, lastLink;
//从指定位置返回LinkedList的iterator
LinkIterator(LinkedList object, int location) {
list = object;
expectedModCount = list.modCount;
//检查角标是否越界
if (location >= 0 && location <= list.size) {
// pos ends up as -1 if list is empty, it ranges from -1 to
// list.size - 1
// if link == voidLink then pos must == -1
//获取LinkedList的head节点
link = list.voidLink;
//根据指定位置判断其位于LinkedList前半部分还是后半部分,
//然后决定是从开始查找,还是从后开始查找,
//找到指定位置的节点。
//这种根据位置来决定从前半部分还是后半部分查找的方法在LinkedList中很常见也很有效
if (location < list.size / 2) {
for (pos = -1; pos + 1 < location; pos++) {
link = link.next;
}
} else {
for (pos = list.size; pos >= location; pos--) {
link = link.previous;
}
}
} else {
throw new IndexOutOfBoundsException();
}
}
//通过iterator添加元素
public void add(ET object) {
if (expectedModCount == list.modCount) {
Link next = link.next;//获取当前节点的下一个节点
//为需要添加的新元素创建一个新的节点对象
//新节点的前一个节点指向当前节点
//新节点的后一个节点指向当前节点的原来的后一节点
//即将新的节点插入原节点于其后一节点之间
Link newLink = new Link(object, link, next);
link.next = newLink;//将当前节点的下一个节点指向新建的节点
next.previous = newLink;//将原节点的后一节点的向前的引用指向新的节点
link = newLink;//将原节点的引用指向新添加的节点
lastLink = null;//将原来最后一个节点的引用释放,因为位置发生改变
pos++; //指针位置移动
expectedModCount++;//预期修改次数加一
list.size++; //LinkedList元素数量加一
list.modCount++; //LinkedList修改次数加一
} else {
throw new ConcurrentModificationException();
}
}
//返回当前指针位置后面是否还有元素
//如果该节点后面是head节点,则其为LinkedList最后一个节点
//否则后面还有其他元素
public boolean hasNext() {
return link.next != list.voidLink;
}
//返回当前指针位置前面是否还有元素
//如果当前节点不是head节点那么其前面还有元素
public boolean hasPrevious() {
return link != list.voidLink;
}
//获取当前指针位置后面的节点中的元素
public ET next() {
if (expectedModCount == list.modCount) {//fail-fase判断
LinkedList.Link next = link.next;//获取当前阶段的下一节点
if (next != list.voidLink) {//判断是否已经到末尾
lastLink = link = next;//更新引用,向前移动
pos++; //指针位置向前移动
return link.data; //返回数据
}
throw new NoSuchElementException();
}
throw new ConcurrentModificationException();
}
//返回下一角标,即指针位置加一
//指针开始位置为-1,角标开始为0
public int nextIndex() {
return pos + 1;
}
//返回当前指针位置的前一个元素
public ET previous() {
if (expectedModCount == list.modCount) {
if (link != list.voidLink) {
lastLink = link;
link = link.previous;
pos--;
return lastLink.data;
}
throw new NoSuchElementException();
}
throw new ConcurrentModificationException();
}
//返回当前指针位置的前一角标,即指针本身位置
//因为指针总是在角标的前一位
public int previousIndex() {
return pos;
}
//移除LinkedList的一个元素
public void remove() {
if (expectedModCount == list.modCount) {
if (lastLink != null) {
Link next = lastLink.next;
Link previous = lastLink.previous;//获取lastLink前后节点引用
next.previous = previous;
previous.next = next;//将lastLink前后节点连接起来
if (lastLink == link) {
pos--; //如果移除的是最后一个节点,指针位置减一
}
link = previous;
lastLink = null;
expectedModCount++;
list.size--;
list.modCount++;
} else {
throw new IllegalStateException();
}
} else {
throw new ConcurrentModificationException();
}
}
//修改lastLink节点的值
public void set(ET object) {
if (expectedModCount == list.modCount) {
if (lastLink != null) {
lastLink.data = object;
} else {
throw new IllegalStateException();
}
} else {
throw new ConcurrentModificationException();
}
}
}
//倒序的iterator
private class ReverseLinkIterator implements Iterator {
private int expectedModCount;
private final LinkedList list;
private Link link;
private boolean canRemove;
ReverseLinkIterator(LinkedList linkedList) {
list = linkedList;
expectedModCount = list.modCount;
link = list.voidLink;
canRemove = false;
}
public boolean hasNext() {
return link.previous != list.voidLink;
}
public ET next() {
if (expectedModCount == list.modCount) {
if (hasNext()) {
link = link.previous;
canRemove = true;
return link.data;
}
throw new NoSuchElementException();
}
throw new ConcurrentModificationException();
}
public void remove() {
if (expectedModCount == list.modCount) {
if (canRemove) {
Link next = link.previous;
Link previous = link.next;
next.next = previous;
previous.previous = next;
link = previous;
list.size--;
list.modCount++;
expectedModCount++;
canRemove = false;
return;
}
throw new IllegalStateException();
}
throw new ConcurrentModificationException();
}
}
//默认的LinkedList构造函数
//创建一个head节点,其前后节点的引用都指向自己
//为空
public LinkedList() {
voidLink = new Link(null, null, null);
voidLink.previous = voidLink;
voidLink.next = voidLink;
}
//使用一个collection创建一个LinkedList
//将collection中所有元素添加到LinkedList中
public LinkedList(Collection collection) {
this();
addAll(collection);
}
//添加元素到指定位置
@Override
public void add(int location, E object) {
if (location >= 0 && location <= size) {
Link link = voidLink;
//获取到指定位置的原有节点
if (location < (size / 2)) {
for (int i = 0; i <= location; i++) {
link = link.next;
}
} else {
for (int i = size; i > location; i--) {
link = link.previous;
}
}
//添加新的节点到原位置节点与其前一个节点之间
//取代原节点的位置
Link previous = link.previous;
Link newLink = new Link(object, previous, link);
previous.next = newLink;
link.previous = newLink;
size++;
modCount++;
} else {
throw new IndexOutOfBoundsException();
}
}
//默认添加元素,添加到末尾
@Override
public boolean add(E object) {
return addLastImpl(object);
}
private boolean addLastImpl(E object) {
Link oldLast = voidLink.previous;
Link newLink = new Link(object, oldLast, voidLink);
voidLink.previous = newLink;
oldLast.next = newLink;
size++;
modCount++;
return true;
}
//添加一个collection中的所有元素到LinkedList中,从指定位置开始
//添加的元素顺序为原collection中的顺序
@Override
public boolean addAll(int location, Collection collection) {
if (location < 0 || location > size) {
throw new IndexOutOfBoundsException();
}
int adding = collection.size();
if (adding == 0) {
return false;
}
Collection elements = (collection == this) ?
new ArrayList(collection) : collection;
Link previous = voidLink;
if (location < (size / 2)) {
for (int i = 0; i < location; i++) {
previous = previous.next;
}
} else {
for (int i = size; i >= location; i--) {
previous = previous.previous;
}
}
Link next = previous.next;
for (E e : elements) {
Link newLink = new Link(e, previous, null);
previous.next = newLink;
previous = newLink;
}
previous.next = next;
next.previous = previous;
size += adding;
modCount++;
return true;
}
@Override
public boolean addAll(Collection collection) {
int adding = collection.size();
if (adding == 0) {
return false;
}
Collection elements = (collection == this) ?
new ArrayList(collection) : collection;
Link previous = voidLink.previous;
for (E e : elements) {
Link newLink = new Link(e, previous, null);
previous.next = newLink;
previous = newLink;
}
previous.next = voidLink;
voidLink.previous = previous;
size += adding;
modCount++;
return true;
}
//添加元素到队列的头部 双端链表的方法
public void addFirst(E object) {
addFirstImpl(object);
}
private boolean addFirstImpl(E object) {
Link oldFirst = voidLink.next;
Link newLink = new Link(object, voidLink, oldFirst);
voidLink.next = newLink;
oldFirst.previous = newLink;
size++;
modCount++;
return true;
}
//添加元素到列表的末尾
public void addLast(E object) {
addLastImpl(object);
}
//清空列表
//将head的前后引用指向自身
@Override
public void clear() {
if (size > 0) {
size = 0;
voidLink.next = voidLink;
voidLink.previous = voidLink;
modCount++;
}
}
//clone方法
//复制一个LinkedList然后将当前list加入复制的列表汇中
@SuppressWarnings("unchecked")
@Override
public Object clone() {
try {
LinkedList l = (LinkedList) super.clone();
l.size = 0;
l.voidLink = new Link(null, null, null);
l.voidLink.previous = l.voidLink;
l.voidLink.next = l.voidLink;
l.addAll(this);
return l;
} catch (CloneNotSupportedException e) {
throw new AssertionError(e);
}
}
//查找列表中是否包含某个元素
//遍历列表
@Override
public boolean contains(Object object) {
Link link = voidLink.next;
if (object != null) {
while (link != voidLink) {
if (object.equals(link.data)) {
return true;
}
link = link.next;
}
} else {
while (link != voidLink) {
if (link.data == null) {
return true;
}
link = link.next;
}
}
return false;
}
//获取指定位置的元素
//熟悉的根据指定的位置来判断从前端还是后端进行遍历
//从中可以看出,根据角标来获取LinkedList的时候,由于每次
//都需要进行遍历,因此效率较低
//严禁通过这种随机访问的形式来进行LinkedList的遍历
@Override
public E get(int location) {
if (location >= 0 && location < size) {
Link link = voidLink;
if (location < (size / 2)) {
for (int i = 0; i <= location; i++) {
link = link.next;
}
} else {
for (int i = size; i > location; i--) {
link = link.previous;
}
}
return link.data;
}
throw new IndexOutOfBoundsException();
}
//返回队列的首元素
public E getFirst() {
return getFirstImpl();
}
private E getFirstImpl() {
Link first = voidLink.next;
if (first != voidLink) {
return first.data;
}
throw new NoSuchElementException();
}
//返回列队的末元素
public E getLast() {
Link last = voidLink.previous;
if (last != voidLink) {
return last.data;
}
throw new NoSuchElementException();
}
//查找指定元素的角标
@Override
public int indexOf(Object object) {
int pos = 0;
Link link = voidLink.next;
if (object != null) {
while (link != voidLink) {
if (object.equals(link.data)) {
return pos;
}
link = link.next;
pos++;
}
} else {
while (link != voidLink) {
if (link.data == null) {
return pos;
}
link = link.next;
pos++;
}
}
return -1;
}
//倒序查找指定元素的角标
@Override
public int lastIndexOf(Object object) {
int pos = size;
Link link = voidLink.previous;
if (object != null) {
while (link != voidLink) {
pos--;
if (object.equals(link.data)) {
return pos;
}
link = link.previous;
}
} else {
while (link != voidLink) {
pos--;
if (link.data == null) {
return pos;
}
link = link.previous;
}
}
return -1;
}
//返回一个List的iterator
@Override
public ListIterator listIterator(int location) {
return new LinkIterator(this, location);
}
//移除指定位置的元素
@Override
public E remove(int location) {
if (location >= 0 && location < size) {
Link link = voidLink;
if (location < (size / 2)) {
for (int i = 0; i <= location; i++) {
link = link.next;
}
} else {
for (int i = size; i > location; i--) {
link = link.previous;
}
}
Link previous = link.previous;
Link next = link.next;
previous.next = next;
next.previous = previous;
size--;
modCount++;
return link.data;
}
throw new IndexOutOfBoundsException();
}
//移除指定元素
@Override
public boolean remove(Object object) {
return removeFirstOccurrenceImpl(object);
}
//移除队列的首元素
public E removeFirst() {
return removeFirstImpl();
}
private E removeFirstImpl() {
Link first = voidLink.next;
if (first != voidLink) {
Link next = first.next;
voidLink.next = next;
next.previous = voidLink;
size--;
modCount++;
return first.data;
}
throw new NoSuchElementException();
}
//移除队列的末元素
public E removeLast() {
return removeLastImpl();
}
private E removeLastImpl() {
Link last = voidLink.previous;
if (last != voidLink) {
Link previous = last.previous;
voidLink.previous = previous;
previous.next = voidLink;
size--;
modCount++;
return last.data;
}
throw new NoSuchElementException();
}
//返回一个倒序的iterator
public Iterator descendingIterator() {
return new ReverseLinkIterator(this);
}
//Deque接口的方法实现 添加元素到队列首位
public boolean offerFirst(E e) {
return addFirstImpl(e);
}
//Deque接口的方法实现,添加元素到队列末位
public boolean offerLast(E e) {
return addLastImpl(e);
}
//Deque接口的方法实现,获取队列首位的元素
//队列为空则返回null
public E peekFirst() {
return peekFirstImpl();
}
//Deque接口方法,获取队列末位元素
//队列为空则返回null
public E peekLast() {
Link last = voidLink.previous;
return (last == voidLink) ? null : last.data;
}
//Deque接口方法
//移除队列首位元素并返回
//队列为空则返回null
public E pollFirst() {
return (size == 0) ? null : removeFirstImpl();
}
//Deque方法
//移除队列末位元素并返回
public E pollLast() {
return (size == 0) ? null : removeLastImpl();
}
//Deque方法
//移除队列首位元素并返回
//与pollFirst方法区别在于队列为空时会抛出异常
public E pop() {
return removeFirstImpl();
}
//Deque方法
//添加元素到队列首位
public void push(E e) {
addFirstImpl(e);
}
//Deque方法
public boolean removeFirstOccurrence(Object o) {
return removeFirstOccurrenceImpl(o);
}
public boolean removeLastOccurrence(Object o) {
Iterator iter = new ReverseLinkIterator(this);
return removeOneOccurrence(o, iter);
}
private boolean removeFirstOccurrenceImpl(Object o) {
Iterator iter = new LinkIterator(this, 0);
return removeOneOccurrence(o, iter);
}
private boolean removeOneOccurrence(Object o, Iterator iter) {
while (iter.hasNext()) {
E element = iter.next();
if (o == null ? element == null : o.equals(element)) {
iter.remove();
return true;
}
}
return false;
}
//修改指定位置的元素
@Override
public E set(int location, E object) {
if (location >= 0 && location < size) {
Link link = voidLink;
if (location < (size / 2)) {
for (int i = 0; i <= location; i++) {
link = link.next;
}
} else {
for (int i = size; i > location; i--) {
link = link.previous;
}
}
E result = link.data;
link.data = object;
return result;
}
throw new IndexOutOfBoundsException();
}
//返回当前列表的元素数量
@Override
public int size() {
return size;
}
//添加元素到队列末位
public boolean offer(E o) {
return addLastImpl(o);
}
//移除并返回队列首位元素
public E poll() {
return size == 0 ? null : removeFirst();
}
//移除并返回队列首位元素
//为空时会抛出异常
public E remove() {
return removeFirstImpl();
}
//返回队列首位元素
//不会删除元素
//为空时会返回null
public E peek() {
return peekFirstImpl();
}
private E peekFirstImpl() {
Link first = voidLink.next;
return first == voidLink ? null : first.data;
}
//获取首位元素
public E element() {
return getFirstImpl();
}
//返回列表的数组形式
@Override
public Object[] toArray() {
int index = 0;
Object[] contents = new Object[size];
Link link = voidLink.next;
while (link != voidLink) {
contents[index++] = link.data;
link = link.next;
}
return contents;
}
//返回列表的数组形式
//如果参数传递的数组够大则使用参数数组
//否则创建新数组
@Override
@SuppressWarnings("unchecked")
public T[] toArray(T[] contents) {
int index = 0;
if (size > contents.length) {
Class ct = contents.getClass().getComponentType();
contents = (T[]) Array.newInstance(ct, size);
}
Link link = voidLink.next;
while (link != voidLink) {
contents[index++] = (T) link.data;
link = link.next;
}
if (index < contents.length) {
contents[index] = null;
}
return contents;
}
//序列化方法
//先写入容量即size
//再写入每个节点
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
stream.writeInt(size);
Iterator it = iterator();
while (it.hasNext()) {
stream.writeObject(it.next());
}
}
//反序列化方法
//先读取容量即size
//再创建LinkedList,读取每个节点加入队列
@SuppressWarnings("unchecked")
private void readObject(ObjectInputStream stream) throws IOException,
ClassNotFoundException {
stream.defaultReadObject();
size = stream.readInt();
voidLink = new Link(null, null, null);
Link link = voidLink;
for (int i = size; --i >= 0;) {
Link nextLink = new Link((E) stream.readObject(), link, null);
link.next = nextLink;
link = nextLink;
}
link.next = voidLink;
voidLink.previous = link;
}
}