LinkedList源码分析
一、准备工作
package com.liu.List;
import sun.util.resources.cldr.it.CalendarData_it_IT;
import java.util.Iterator;
import java.util.LinkedList;
public class LinkedList_ {
public static void main(String[] args) {
LinkedList<Object> linkedList = new LinkedList<>();
linkedList.add(1);
linkedList.add(2);
linkedList.add(3);
Iterator<Object> iterator = linkedList.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println("linkedList=>"+linkedList);
}
linkedList.remove();
System.out.println(linkedList);
}
}
二、源码分析
第一次添加
进入构造函数
/**
* Constructs an empty list.
*/
public LinkedList() {
}
跳出构造函数
进行装箱操作
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
进入add方法
public boolean add(E e) {
linkLast(e);
return true;
}
进入linkLast(双向链表的尾插法)
/**
* Links e as last element.
*/
void linkLast(E e) {
//新建一个节点l指向last
final Node<E> l = last;
//新建节点newNode, new Node<>(pre,item,next) 所以l为newNode的pre结点,item为
//newNode的数据域,null为newNode的next节点
final Node<E> newNode = new Node<>(l, e, null);
//last指向newNode
last = newNode;
if (l == null)//若链表为空
first = newNode;//则将新节点指定为first
else
l.next = newNode;//将newNode插入到最后一个节点后
size++;
modCount++;
}
流程图
第二次添加
进入add
public boolean add(E e) {
linkLast(e);
return true;
}
进入linkLast(e);
/**
* 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++;
}
流程图
跳出add方法
remove方法
进入remove
public E remove() {
return removeFirst();
}
进入removeFirst()
public E removeFirst() {
final Node<E> f = first; //新建一个指向first的结点f
if (f == null)//判断链表是否为空
throw new NoSuchElementException();
return unlinkFirst(f);
}
进入unlinkFirst()
/**
* Unlinks non-null first node f.
*/
private E unlinkFirst(Node<E> f) {
// assert f == first && f != null;
final E element = f.item; //记录first节点的元素值
final Node<E> next = f.next; //新建一个next结点,记录first节点的下一结点
f.item = null; //清空first结点
f.next = null; // help GC //断掉first指向下一节点的指针
first = next; //重新将first结点指向下一节点
if (next == null)//若next为null,表示链表为空
last = null; //则last也指向null
else
next.prev = null;//将next节点的pre指针断掉
size--;
modCount++;
return element;
}
三、总结(重点)
LinkedList底层是双向链表
remove()方法默认移除第一个元素,同样也有移除末尾元素的方法,所以可以当作双端队列来使用
LinkedList插入方式为尾插法
LinkedList适用于大量数据的增删操作,因为可以动态添加删除节点,而无需考虑扩容问题
ArrayList适用于大量数据的修改和查询操作(可以直接通过下标访问),但增删效率较低,因为底层为数组,需要考虑扩容问题