阅读java.util.LinkedList笔记
1,LinkedList类定义实现和继承关系:
public class LinkedList extends AbstractSequentialList implements List, Deque, Cloneable, java.io.Serializable{…}
2,LinkedList中定义的成员变量:
transient int size = 0;
transient Node first; //第一个节点
transient Node last; //最后一个节点
a,transient关键字的作用,在已实现序列化的类中,有的变量不需要保存在磁盘中,就要transient关键字修饰,如银行卡密码等,就这个作用------在已序列化的类中使变量不序列化
b,Node 是LinkedList的一个内部类,主要用于保存上一个、当前和下一个元素的引用
c,first和last需要维持一个不变量,也就是first和last始终都要维持两种状态:
首先,如果双端链表为空的时候,两个都必须为null
如果链表不为空,那么first的前驱节点一定是null,first的item一定不为null,同理,last的后继节点一定是null,last的item一定不为null。
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;
}
}
3,有两个构造方法,一个无参一个有参,有参的构造方法:
//构造方法传入Collection, 那么将Collection转换为链表结构
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
4,linkFirst(E e)方法:
// 插入第一个节点
private void linkFirst(E e) {
final Node<E> f = first;
final Node<E> newNode = new Node<>(null, e, f);
first = newNode;
if (f == null)
last = newNode;
else
f.prev = newNode;
size++;
//表示列表结构被修改的次数
modCount++;
}
我们开始分析代码,首先用f来临时保存未插入前的first节点,然后调用的node的构造函数新建一个值为e的新节点,这个节点插入之后将作为first节点,所以新节点的前驱节点为null,值为e,后继节点是f,也就是未插入前的first节点。
然后就是维持不变量,首先第一种情况,如果f==null,那就说明插入之前,链表是空的,那么新插入的节点不仅是first节点还是last节点,所以我们要更新last节点的状态,也就是last现在要指向新插入的newNode。
如果f!=null那么就说明last节点不变,但是要更新f的前驱节点为newNode,维持first节点的不变量。
最后size加一就完成了操作。
同理还有:
linkLast(E e) , 插入最后一个节点,add内部就是直接调用该方法
linkBefore(E e , Node succ) ,在给定节点前插入节点e
unlinkFirst(Node f) , 删除指定节点前所有的节点(包括自己),removeFirst()内部直接调用该方法
unlinkLast<Node l ) , 删除指定节点后所有的节点(包括自己),removeLast()内部直接调用该方法
unlink(Node x)。删除指定的节点
5,boolean contains(Object o) 方法:
public boolean contains(Object o) {
//返回下标不等与-1代表包含o元素
return indexOf(o) != -1;
}