LinkedList流程图
LinkedList源码
step1:new LinkedList();
初始化
/**
* Constructs an empty list.
*/
public LinkedList() {
}
step2:list.add(obj)
新增元素
/**
* 链表元素对象结构
*/
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;
}
}
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
*
* 新增元素
*/
public boolean add(E e) {
linkLast(e);
return true;
}
/**
* Links e as last element.
* 将新添加元素e作为链表的最后一个元素,并维护进去
*/
void linkLast(E e) {
//获取last节点
final Node<E> l = last;
//构建新节点
final Node<E> newNode = new Node<>(l, e, null);
//将last指针指向当前节点
last = newNode;
//校验是否是第一个节点
if (l == null){
//如果是第一个添加的元素,则first指针指向该节点
first = newNode;
} else{
//如果不是第一个添加的元素,则更新l的后置节点指向新添加的元素节点
l.next = newNode;
}
//链表长度加1
size++;
//链表修改次数加1
modCount++;
}
step3:list.remove()
移除元素
/**
* 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();
}
/**
* Removes and returns the first element from this list.
*
* @return the first element from this list
* @throws NoSuchElementException if this list is empty
*/
public E removeFirst() {
//获取头节点
final Node<E> f = first;
//校验头节点是否为空
if (f == null)
//若为空,则抛出异常
throw new NoSuchElementException();
return unlinkFirst(f);
}
/**
* Unlinks non-null first node f.
* 解绑头节点
*/
private E unlinkFirst(Node<E> f) {
// assert f == first && f != null;
//获取 f节点的element
final E element = f.item;
//获取next指针指向的下一个节点
final Node<E> next = f.next;
//将 f节点设为null
f.item = null;
//将 f节点的next指针指向null
f.next = null; // help GC
//将first指针指向原本的next节点
first = next;
//校验next是否为null
if (next == null){
//若next节点为null,将last指针指向null
last = null;
}else{
//若next节点不为空,将next节点的前置指针指向null,即将next节点变为头节点
next.prev = null;
}
//链表长度减1
size--;
//链表修改次数加1
modCount++;
//返回 f节点的元素
return element;
}
step4:list.remove(index)
根据下标移除元素
/**
*
*/
public E remove(int index) {
//校验下标是否越界
checkElementIndex(index);
//断开待删除节点的链接,并返回该节点
return unlink(node(index));
}
/**
* 校验下标是否越界
*/
private void checkElementIndex(int index) {
if (!isElementIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
/**
* Tells if the argument is the index of an existing element.
* 校验下标是否越界,与ArrayList不同,是否越界需要自己判断
*/
private boolean isElementIndex(int index) {
return index >= 0 && index < size;
}
/**
* Returns the (non-null) Node at the specified element index.
* 根据传入的index,返回对应的节点node
*/
Node<E> node(int index) {
// assert isElementIndex(index);
//如果需要获取的index小于总长度size的一半,则从头部开始向后遍历查找
if (index < (size >> 1)) {
//从头部开始向后查找
Node<E> x = first;
for (int i = 0; i < index; i++){
//从first节点向后next查找,直到index下标node,然后返回
x = x.next;
}
return x;
} else {
//从尾部开始向前遍历查找
Node<E> x = last;
for (int i = size - 1; i > index; i--){
//从last节点向前prev查找,直到index下标node,然后返回
x = x.prev;
}
return x;
}
}
/**
* Unlinks non-null node x.
* 从链表中删除 x节点的链接
*/
E unlink(Node<E> x) {
// assert x != null;
//获取x节点的元素,前置节点,后置节点
final E element = x.item;
final Node<E> next = x.next;
final Node<E> prev = x.prev;
//校验x节点是否为第一个节点,x.prev为null,表示x节点为第一个节点
if (prev == null) {
//若是第一节点,则将first头指针指向x节点的后置节点
first = next;
} else {
//若不是第一节点,将x节点前置节点的后置指针指向x节点的后置节点
prev.next = next;
//断开x节点的前置指针,将x节点的前置指针指向null
x.prev = null;
}
//校验x节点是否为末节点,x.next为null,标识x节点为末节点
if (next == null) {
//若是末节点,将last指针指向x节点的前置节点
last = prev;
} else {
//若不是末节点,将x节点后置节点的前置指针指向x节点的前置节点
next.prev = prev;
//断开x节点的后置指针,将x节点的后置指针指向null
x.next = null;
}
//将x节点的element设置为null
x.item = null;
//链表长度减1
size--;
//链表修改长度加1
modCount++;
//返回x节点的element
return element;
}