一、添加结点:add();方法
示例代码
LinkedList linkedList = new LinkedList();
linkedList.add(1);
linkedList.add(2);
linkedList.add(3);
System.out.println("linkedList = " + linkedList);
1、首先会进入到无参的构造方法里
此时会new出一个linkedList类型的对象,里面有整型遍历size和modCount,结点类型first和last
2、将基本数据类型装箱为引用数据类型
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
3、开始添加数据
首先带着要添加的数据调用linkLast方法
public boolean add(E e) {
linkLast(e);
return true;
}
linkLast方法(关键)
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++;
}
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
这三行代码执行完之后是下面这个情况
first = newNode;
然后size++记录链表的长度,modCount++记录修改的次数
size++;
modCount++;
此时已经添加完毕,开始逐步返回
4、第二次及其以后添加数据
首先还是一个先把基本数据类型转换给引用数据类型的过程
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
然后执行下面这三行代码
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
此时是这么个情况
然后因为此时指针l指向的是结点1,所以不为空,执行的是这个语句
l.next = newNode;
此时一个双向链表就构建好了,后面添加结点都是类似的
二、删除节点:remove(); 方法
linkedList.remove(); //这里默认删除的是第一个结点
1、首先会进入到remove(); 方法里面,然后remove();
调用removeFirst(); 方法所以默认删除的是第一个元素
public E remove() {
return removeFirst();
}
2、removeFirst(); 方法调用unlinkFirst(); 方法
public E removeFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return unlinkFirst(f);
}
2.1、把first指针赋值给f指针
2.2、判断f指针是否为空,为空抛出NoSuchElementException异常
2.3、进入unlinkFirst(); 方法
3、unlinkFirst(); 进行删除结点操作
private E unlinkFirst(Node<E> f) {
// assert f == first && f != null;
final E element = f.item;
final Node<E> next = f.next;
f.item = null;
f.next = null; // help GC
first = next;
if (next == null)
last = null;
else
next.prev = null;
size--;
modCount++;
return element;
}
此时f指向第一节结点
final E element = f.item;
3.1、把f.item(也就是第一个结点的元素)赋值给element,以便最后返回。
final Node<E> next = f.next;
3.2、创建一个next指针指向f的下一个结点,也就是第二个节点
f.item = null;
f.next = null; // help GC
first = next;
3.3、把f.item、f.next置为空,next指针赋值给first,即第一个节点的元素为空,和第一个节点不再指向第二个节点,first指针指向第二节点
if (next == null)
last = null;
else
next.prev = null;
3.4、判断第二个节点是否为空,是的话置为null,否则next指针的前驱指针置为null,此时第二个节点指向第一个节点的指针也断开了,第一个节点就会被JVM回收。
size--;
modCount++;
return element;