1. LinkedList的定义

   1.1  继承于AbstractSequentialList的双向链表,可以被当作堆栈队列双端队列进行操作

1.2  有序,非线程安全的双向链表,默认使用尾部插入法

1.3 适用于频繁新增或删除场景,频繁访问场景请选用ArrayList

1.4 插入和删除时间复杂为O(1),其余最差O(n)

1.5 由于实现Deque接口,双端队列相关方法众多

2. LinkedList的继承体系

      

  • 继承 AbstractSequentialList,能被当作堆栈、队列或双端队列进行操作
  • 实现 List 接口,能进行队列操作
  • 实现 Deque 接口,能将LinkedList当作双端队列使用
  • 实现 Cloneable 接口,重写 clone() ,能克隆(浅拷贝)
  • 实现 java.io.Serializable 接口,支持序列化

3. LinkedList的源码实现

    

 public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable { /**
* 记录当前链表中元素的个数
*/
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; /**
* Constructs an empty list.
* 默认空构造器 -- 注意LinkedList并不提供指定容量的构造器
*/
public LinkedList() {
} /**
* 支持将一个Collection对象转换为linkedList对象
*/
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
} /**
* 从头部开始添加一个元素
*/
private void linkFirst(E e) {
//获取头部节点
final Node<E> f = first; //组建新的节点,新的节点的prev为null,并赋值给头部节点
final Node<E> newNode = new Node<>(null, e, f);
first = newNode; //头节点==null.说明链表中没有元素
if (f == null)
last = newNode;
else
f.prev = newNode; //设置旧的头节点的前一个节点为新建的节点
size++;
modCount++;
} /**
* Links e as last element.
* 从尾部开始添加一个元素
*/
void linkLast(E e) { //获取尾部节点
final Node<E> l = last; //组建新的节点,新节点的next节点为null,并将新的节点赋值给尾部节点
final Node<E> newNode = new Node<>(l, e, null);
last = newNode; //尾部节点为null,说明链表中没有元素
if (l == null)
first = newNode;
else
l.next = newNode; //设置旧的尾节点的next为新建的节点
size++;
modCount++;
} /**
* 在指定的节点之前添加元素
*/
void linkBefore(E e, Node<E> succ) { //获取指定节点的prev
final Node<E> pred = succ.prev; //构建新的节点
final Node<E> newNode = new Node<>(pred, e, succ);
//将新建的节点设置为指定节点的prev
succ.prev = newNode; //判断prev是否为头结点
if (pred == null)
first = newNode;
else
pred.next = newNode; //设置新节点为prev的next节点
size++;
modCount++;
} /**
* 移除头部节点
*/
private E unlinkFirst(Node<E> f) {
// assert f == first && f != null;
final E element = f.item; //获取头节点的next,并赋值给first
final Node<E> next = f.next;
f.item = null;
f.next = null; // help GC
first = next; //next == null,说明链表中已经没有元素
if (next == null)
last = null;
else
next.prev = null; //设置头结点的prev为null
size--;
modCount++;
return element;
} /**
* 移除尾部节点
*/
private E unlinkLast(Node<E> l) {
// assert l == last && l != null;
final E element = l.item; //获取尾部节点的prev节点,并赋值为last节点
final Node<E> prev = l.prev;
l.item = null;
l.prev = null; // help GC
last = prev; //prev == null,说明链表中已经没有元素
if (prev == null)
first = null;
else
prev.next = null; //设置尾节点的next为空
size--;
modCount++;
return element;
} /**
* 移除链表中的某个节点
*/
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
prev.next = next;
//当前节点的prev置为null
x.prev = null;
} //要移除的节点是否是尾节点
if (next == null) {
last = prev;
} else {
//当前节点的next节点的prev节点赋值为当前节点的prev
next.prev = prev;
x.next = null;
} //将当前节点置为null
x.item = null;
size--;
modCount++;
return element;
} /**
* 获取链表中的第一个元素
*/
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 E removeFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException(); //执行移除头部节点的方法
return unlinkFirst(f);
} /**
* 移除链表中的最后一个元素并返回
*/
public E removeLast() {
final Node<E> l = last;
if (l == null)
throw new NoSuchElementException(); //执行移除尾部节点的方法
return unlinkLast(l);
} /**
* 在链表的头部添加节点
*/
public void addFirst(E e) {
linkFirst(e);
} /**
* 在链表的尾部添加节点
*/
public void addLast(E e) {
linkLast(e);
} /**
* 链表中是否包含某个元素
*/
public boolean contains(Object o) {
return indexOf(o) != -1;
} /**
* 链表中元素的个数
*/
public int size() {
return size;
} /**
* 添加一个元素到链表中
* 默认是尾部添加
* 成功则返回true
*/
public boolean add(E e) {
linkLast(e);
return true;
} /**
* 移除链表中的某个元素
*/
public boolean remove(Object o) {
if (o == null) {
//遍历查找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)) {
//执行移除的方法
unlink(x);
return true;
}
}
}
return false;
} /**
* 将一个collection对象转换为链表中的节点
*/
public boolean addAll(Collection<? extends E> c) {
return addAll(size, c);
} /**
*
*/
public boolean addAll(int index, Collection<? extends E> c) { //检查索引的合理性
checkPositionIndex(index); //将collection对象转换为数组,数组为空则直接返回
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;
else
pred.next = newNode;
pred = newNode;
} //如果succ为null,则是在尾部进行节点的插入
if (succ == null) {
last = pred;
} else {
//将新插入的节点和后面的节点进行链接
pred.next = succ;
succ.prev = pred;
} size += numNew;
modCount++;
return true;
} /**
* 清空链表中的元素
*/
public void clear() { //循环设置链表的值为null,加快gc
for (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++;
} /**
* 获取指定位置的元素
*/
public E get(int index) {
//检查索引的合理性
checkElementIndex(index);
return node(index).item;
} /**
* 替换指定位置上的元素并返回旧的元素
*/
public E set(int index, E element) {
checkElementIndex(index);
//找到指定元素所在的节点
Node<E> x = node(index);
E oldVal = x.item;
x.item = element;
return oldVal;
} /**
* 在指定的位置添加元素
*/
public void add(int index, E element) {
checkPositionIndex(index); if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
} /**
* 移除指定位置的元素
*/
public E remove(int index) {
//检查索引的合理性
checkElementIndex(index);
//进行指定位置上的节点移除
return unlink(node(index));
} private boolean isElementIndex(int index) {
return index >= 0 && index < size;
} private boolean isPositionIndex(int index) {
return index >= 0 && index <= size;
} private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+size;
} /**
* 检查索引是否合理
* @param index
*/
private void checkElementIndex(int index) {
if (!isElementIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
} private void checkPositionIndex(int index) {
if (!isPositionIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
} /**
* 返回某个位置上的节点元素
*/
Node<E> node(int 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;
}
} /**
* 元素存在于链表中,则返回所在的节点的位置
* 否则返回-1
*/
public int indexOf(Object o) {
//初始化为0
int index = 0;
//如果元素为null,返回第一个查找到的null的位置
if (o == null) {
//遍历链表,查找null元素,并增加index的值
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null)
return index;
index++;
}
} else {
//遍历链表,查找元素,并增加index的值
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item))
return index;
index++;
}
}
return -1;
} /**
* 从链表的尾节点开始查找指定的元素
* 并返回指定元素的位置
* 没有找到返回-1
*/
public int lastIndexOf(Object o) {
int index = size;
//指定的元素是否为null
if (o == null) {
//遍历查找null元素
for (Node<E> x = last; x != null; x = x.prev) {
index--;
if (x.item == null)
return index;
}
} else {
//遍历查找指定的元素
for (Node<E> x = last; x != null; x = x.prev) {
index--;
if (o.equals(x.item))
return index;
}
}
return -1;
} /**
* 进行出队列的操作
*/
public E peek() {
final Node<E> f = first;
return (f == null) ? null : f.item;
} /**
* 获取链表中的一个元素
* 默认返回头结点的元素
*/
public E element() {
return getFirst();
} /**
* 进行出队列的操作
* 并移除元素
*/
public E poll() {
final Node<E> f = first;
return (f == null) ? null : unlinkFirst(f);
} /**
* 移除链表中的元素
* 默认为头结点的元素
*/
public E remove() {
return removeFirst();
} /**
* 添加元素,默认在尾部添加
*/
public boolean offer(E e) {
return add(e);
} /**
* 在链表的头部添加元素
* 成功则返回true
*/
public boolean offerFirst(E e) {
addFirst(e);
return true;
} /**
* 在尾部添加元素
*/
public boolean offerLast(E e) {
addLast(e);
return true;
} /**
* 获取第一个元素
*/
public E peekFirst() {
final Node<E> f = first;
return (f == null) ? null : f.item;
} /**
* 获取最后一个元素
*/
public E peekLast() {
final Node<E> l = last;
return (l == null) ? null : l.item;
} /**
* 获取第一个元素
* 并移除
*/
public E pollFirst() {
final Node<E> f = first;
return (f == null) ? null : unlinkFirst(f);
} /**
* 获取最后一个元素
* 并移除
*/
public E pollLast() {
final Node<E> l = last;
return (l == null) ? null : unlinkLast(l);
} /**
* 头部添加元素
*/
public void push(E e) {
addFirst(e);
} /**
* 移除头部元素
*/
public E pop() {
return removeFirst();
} /**
* 从头查找,并移除指定的元素
* 成功返回true
*/
public boolean removeFirstOccurrence(Object o) {
return remove(o);
} /**
* 从尾部查找,并移除指定的元素
* 成功返回true
*/
public boolean removeLastOccurrence(Object o) {
if (o == null) {
//遍历查找指定的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;
} /**
* 从指定位置开始获取链表的迭代器
*/
public ListIterator<E> listIterator(int index) {
checkPositionIndex(index);
return new ListItr(index);
} /**
* 链表的内部类
* 一个迭代器对象
* @author Administrator
*
*/
private class ListItr implements ListIterator<E> {
private Node<E> lastReturned;
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;
else
nextIndex--;
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)
linkLast(e);
else
linkBefore(e, next);
nextIndex++;
expectedModCount++;
} public void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (modCount == expectedModCount && nextIndex < size) {
action.accept(next.item);
lastReturned = next;
next = next.next;
nextIndex++;
}
checkForComodification();
} final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
} /**
* 链表中保存的节点对象
* @param <E>
*/
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;
}
} /**
* @since 1.6
*/
public Iterator<E> descendingIterator() {
return new DescendingIterator();
} /**
* Adapter to provide descending iterators via ListItr.previous
*/
private class DescendingIterator implements Iterator<E> {
private final ListItr itr = new ListItr(size());
public boolean hasNext() {
return itr.hasPrevious();
}
public E next() {
return itr.previous();
}
public void remove() {
itr.remove();
}
} /**
* 调用父类进行链表的克隆
* @return
*/
@SuppressWarnings("unchecked")
private LinkedList<E> superClone() {
try {
return (LinkedList<E>) super.clone();
} catch (CloneNotSupportedException e) {
throw new InternalError(e);
}
} /**
* 进行链表的克隆
*/
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;
} /**
* 将链表转换为Object类型的数组
*/
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;
} /**
* 将链表转换为指定类型的数组
*/
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
if (a.length < size)
a = (T[])java.lang.reflect.Array.newInstance(
a.getClass().getComponentType(), size);
int i = 0;
Object[] result = a;
for (Node<E> x = first; x != null; x = x.next)
result[i++] = x.item; if (a.length > size)
a[size] = null; return a;
} private static final long serialVersionUID = 876323262645176354L; /**
* 序列化链表中的元素
*/
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
// Write out any hidden serialization magic
s.defaultWriteObject(); // Write out size
s.writeInt(size); // Write out all elements in the proper order.
for (Node<E> x = first; x != null; x = x.next)
s.writeObject(x.item);
} /**
* 反序列化链表中的元素
*/
@SuppressWarnings("unchecked")
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
// Read in any hidden serialization magic
s.defaultReadObject(); // Read in size
int size = s.readInt(); // Read in all elements in the proper order.
for (int i = 0; i < size; i++)
linkLast((E)s.readObject());
} /**
* java8新增的返回
* 返回一个并行的分片迭代器
*/
@Override
public Spliterator<E> spliterator() {
return new LLSpliterator<E>(this, -1, 0);
} /** A customized variant of Spliterators.IteratorSpliterator */
static final class LLSpliterator<E> implements Spliterator<E> {
static final int BATCH_UNIT = 1 << 10; // batch array size increment
static final int MAX_BATCH = 1 << 25; // max batch array size;
final LinkedList<E> list; // null OK unless traversed
Node<E> current; // current node; null until initialized
int est; // size estimate; -1 until first needed
int expectedModCount; // initialized when est set
int batch; // batch size for splits LLSpliterator(LinkedList<E> list, int est, int expectedModCount) {
this.list = list;
this.est = est;
this.expectedModCount = expectedModCount;
} final int getEst() {
int s; // force initialization
final LinkedList<E> lst;
if ((s = est) < 0) {
if ((lst = list) == null)
s = est = 0;
else {
expectedModCount = lst.modCount;
current = lst.first;
s = est = lst.size;
}
}
return s;
} public long estimateSize() { return (long) getEst(); } public Spliterator<E> trySplit() {
Node<E> p;
int s = getEst();
if (s > 1 && (p = current) != null) {
int n = batch + BATCH_UNIT;
if (n > s)
n = s;
if (n > MAX_BATCH)
n = MAX_BATCH;
Object[] a = new Object[n];
int j = 0;
do { a[j++] = p.item; } while ((p = p.next) != null && j < n);
current = p;
batch = j;
est = s - j;
return Spliterators.spliterator(a, 0, j, Spliterator.ORDERED);
}
return null;
} public void forEachRemaining(Consumer<? super E> action) {
Node<E> p; int n;
if (action == null) throw new NullPointerException();
if ((n = getEst()) > 0 && (p = current) != null) {
current = null;
est = 0;
do {
E e = p.item;
p = p.next;
action.accept(e);
} while (p != null && --n > 0);
}
if (list.modCount != expectedModCount)
throw new ConcurrentModificationException();
} public boolean tryAdvance(Consumer<? super E> action) {
Node<E> p;
if (action == null) throw new NullPointerException();
if (getEst() > 0 && (p = current) != null) {
--est;
E e = p.item;
current = p.next;
action.accept(e);
if (list.modCount != expectedModCount)
throw new ConcurrentModificationException();
return true;
}
return false;
} public int characteristics() {
return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
}
} }

LinkedList的源码分析的更多相关文章

  1. LinkedList 的源码分析

    LinkedList是基于双向链表数据结构来存储数据的,以下是对LinkedList  的 属性,构造器 ,add(E e),remove(index),get(Index),set(inde,e)进 ...

  2. Java的LinkedList底层源码分析

    首先我们先说一下,源码里可以看出此类不仅仅用双向链表实现了队列数据结构的功能,还提供了链表数据结构的功能.

  3. LinkedList<E>源码分析

    LinkedList的数据结构就是双向链表,如下所示: private static class Node<E> { E item;//数据元素 Node<E> next;// ...

  4. LinkedList的源码分析(基于jdk1.8)

    1.初始化 public LinkedList() { } 并未开辟任何类似于数组一样的存储空间,那么链表是如何存储元素的呢? 2.Node类型 存储到链表中的元素会被封装为一个Node类型的结点.并 ...

  5. Java——LinkedList底层源码分析

    1.简介 LinkedList 是用链表结构存储数据的,很适合数据的动态插入和删除,随机访问和遍历速度比较慢.另外,他还提供了 List 接口中没有定义的方法,专门用于操作表头和表尾元素,可以当作堆栈 ...

  6. 集合框架——LinkedList集合源码分析

    目录 示例代码 底层代码 第1步(初始化集合) 第2步(往集合中添加一个元素) 第3步(往集合中添加第二个元素) 第4步(往集合中添加第三个元素) LinkedList添加元素流程示意图 第5步(删除 ...

  7. 集合之LinkedList(含JDK1.8源码分析)

    一.前言 LinkedList是基于链表实现的,所以先讲解一下什么是链表.链表原先是C/C++的概念,是一种线性的存储结构,意思是将要存储的数据存在一个存储单元里面,这个存储单元里面除了存放有待存储的 ...

  8. LinkedList源码分析和实例应用

    1. LinkedList介绍 LinkedList是继承于AbstractSequentialList抽象类,它也可以被当作堆栈.队列或者双端队列使用. LinkedList实现了Deque接口,即 ...

  9. [源码分析]ArrayList和LinkedList如何实现的?我看你还有机会!

    文章已经收录在 Github.com/niumoo/JavaNotes ,更有 Java 程序员所需要掌握的核心知识,欢迎Star和指教. 欢迎关注我的公众号,文章每周更新. 前言 说真的,在 Jav ...

随机推荐

  1. Jmeter编写Base64加密函数

    方法一: 使用Beanshell Sampler.BSF Sampler等实现,现已Base64加密为例,脚本如下: import sun.misc.BASE64Decoder; String res ...

  2. (转)memcached学习笔记1(windows 7 64bit 环境下安装memcached)

    windows 7 64bit 环境下安装memcached 1.下载后解压到D:\memcached(下载地址:memcached-win64下载地址) 2.安装到windows服务,打开cmd命令 ...

  3. (转)SimpleDateFormat使用详解

    1 SimpleDateFormat 介绍 public class SimpleDateFormat extends DateFormat SimpleDateFormat 是一个以国别敏感的方式格 ...

  4. 内核对象kobject和sysfs(1)——概述

    内核对象kobject和sysfs(1)--概述 问题: 在走读驱动代码时,经常看见kref,kobj,sysfs这些结构,这些结构到底有什么作用?如何理解并使用这些结构呢?这将在接下来的这一系列文章 ...

  5. 怎么关闭wps热点?永久关闭wps右下角弹窗的方法!

    wps热点总是开机或者开启WPS后在任务栏闪烁,影响心情,百度了一下找到的方法也过时了.我的是WIN10系统 所以自己摸索了一下,找到了解决办法.其实还是用空白文件替换wps热点的.exe文件,只是这 ...

  6. JAVA多线程之wait/notify

    本文主要学习JAVA多线程中的 wait()方法 与 notify()/notifyAll()方法的用法. ①wait() 与 notify/notifyAll 方法必须在同步代码块中使用 ②wait ...

  7. Redis-位图法实现简单统计

    比如一个网站有1亿个用户, 现在要统计一周内连续登录的用户 方法: 可以用一个字节8个位表示7个人, 首位不算固定为0, 若某人周一登录则置为1, 没登录则为0 127.0.0.1:6379> ...

  8. pick定理详解

    一.概念 假设P的内部有I(P)个格点,边界上有B(P)个格点,则P的面积A(P)为:A(P)=I(P)+B(P)/2-1. 二.说明 Pick定理主要是计算格点多边形(定点全是格点的不自交图形)P的 ...

  9. Dubbo负载均衡策略

    在集群负载均衡时,Dubbo提供了多种均衡策略,缺省为random随机调用. 可以自行扩展负载均衡策略,参见:负载均衡扩展Random LoadBalance 随机,按权重设置随机概率. 在一个截面上 ...

  10. Ext js Grid

    Ext.onReady(function () {                   var proxy = new Ext.data.HttpProxy({                  ur ...