LinkedList
-
底层数据结构是
双向链表
-
实现了
Deque
接口,Deque接口继承了Queue接口,所以说LinkedList可以被当作队列
,栈
来使用 -
成员变量
- size 链表的大小
- first 头节点
- last 尾节点
-
构造方法
-
空构造
-
集合构造
public LinkedList(Collection<? extends E> c) { this(); addAll(c); }
-
-
核心操作方法
-
add方法
-
逻辑:向链表的尾部追加元素
-
源码
public boolean add(E e) { linkLast(e); return true; }
-
linkLast方法
void linkLast(E e) { // l = 尾节点 final Node<E> l = last; // 临时Node 元素 -> e 前节点 等于 旧的last final Node<E> newNode = new Node<>(l, e, null); // 尾节点 -> e last = newNode; // 尾节点为空 -> 链表就为空 // 因为如果是一个元素的话,first=last if (l == null) // 让头 -> e first = newNode; else // last <=> l l.next = newNode; size++; modCount++; }
-
-
remove方法
-
逻辑:迭代 ,equals判断,存在就删除,指针(Node)位置调整
-
源码
public boolean remove(Object o) { if (o == null) { // 判断链表里面的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; }
-
unlink方法
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; }
-
图示
-
-
get方法
-
逻辑
- 检查位置是否合法(
本质就是index与size作比较
) - 返回元素
- 检查位置是否合法(
-
源码
public E get(int index) { checkElementIndex(index); return node(index).item; }
-
checkElementIndex(index)方法
private void checkElementIndex(int index) { // 做一个异常抛出 if (!isElementIndex(index)) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }
-
isElementIndex(index)方法
private boolean isElementIndex(int index) { // index 范围在 0~size之间就是合法的 return index >= 0 && index < size; }
-
node(index).item;
Node<E> node(int index) { // 断言 下标不超出限制 // assert isElementIndex(index); // 为了速度和性能的提升 // 判断 index 离哪段比较近,那么就从那端开始遍历 if (index < (size >> 1)) { // index < 大小的一半 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; } }
-
-
set方法
-
逻辑
- 检查边界
- 调用node()查找Node
- Node的
item
域赋值为新值 - 返回老值
-
源码
public E set(int index, E element) { // 检查边界 checkElementIndex(index); // 调用node()查找Node Node<E> x = node(index); E oldVal = x.item; // Node的item域赋值为新值 x.item = element; // 返回老值 return oldVal; }
-
-