首先说一些要知道的结论
1.LinkdeList是属于List的一个实现类。他是以双向链表的形式存储的。
双链表结构图
可以看到LinkedList中包含几个属性,size表示当前链表结点的个数,first表示头指针,last表示尾指针也就是上面的tail。在LinkedList中有一个无参构造器
我们用一个实例来演示一下源码。
LinkedList linkedList = new LinkedList();
linkedList.add(1);
在第一句设一个断点我们来debug一下。
public LinkedList() {
}
// LinkedList linkedList = new LinkedList();这一句跳进来他会先进来调用一个无参构造器
在调用完这个构造器后,我们来看看LinkedList中现在有啥
size为0,头指针和尾指针都指向null也就是说他这个创建了一个LinkdeList对象就是对一个链表的初始化动作,你还没有往里面添加结点。
然后我们执行下一句add(1);跳进来
他首先进行的是对这个基本数据类型装箱的动作这没啥好说的。我们跳出来在追进去
此时他执行的是LinkedList中的add并且把刚刚添加的值1作为参数e传进来了,在add方法体中第一句调用的是linkLast方法并把e作为参数传过去,这个方法的作用就是在你刚刚那个空链表的屁股后面追进一个结点,但因为这个链表是空链表所以他追进去就是第一个结点。我们追进linkLast方法中去看看。
进到方法体中第一句他是用一个引用变量L来保存当前链表对象的尾指针last,因为当前链表一个结点也没有所以尾指针就是为空。(注意啊尾指针不是表示链表的最后一个结点中的next那个指针啊而是直接指向最后一个结点的指针)
执行到第二句,他现在才真正开始创建了一个新的结点用来实现add(1);,里面传入了三个参数,这三个参数创建了这样一个结点 | L | item | null | 你看得懂的。然后再把尾指针last指向这个追加的结点,因为你是在最后面追加一个结点嘛所以最后尾指针肯定是指向你这个新添加的结点的。接着下面进行判断,如果你这个 | L | item | null | 中的L为null,也就是说这个判断你这个结点前面有没有结点,如果是空则表示你只有一个结点那么让头指针也指向你这个结点,否则L.next = newNode;表示的是让你的前一个结点的next指针指向你新创建的这个结点。执行完后size加一,也就是链表结点的个数+1,modeCount表示集合修改的次数。最后你执行完后当前链表是这样的
就是这个鸟样
其实这里面双向链表的CRUD底层的源码操作是跟数据结构中一样的所以其实这个不需要再看了,