天天看点

LinkedList 添加元素源码解析

LinkedList添加元素有两个方法:add(E e)和add(int index,E e)。

add(E e)是直接在队尾添加元素。再看一下linkLast(E e)方法,源码如下。

LinkedList会记录链表的最后一个节点last,

首先创建新的节点,新节点的pre就是队列的最后一个节点last,新节点的next为null,

如果last为空表示这个链表为空,新节点就是首节点first。

如果last不为空表示链表不为空,将last节点的next指针指向新节点。

add(int index,E e)是根据元素插入到指定位置上,index表示链表的位置

首先检查index是否超过链表大小,即index 是否会大于链表的size。

如果index等于链表的大小,添加元素就是在链表队尾添加元素,和add(E e) 操作一致。

如果不等会size大小就调用linkBefore方法,首先在该方法的第二个参数使用了node方法。node方法源码如下:

node方法通过链表的位置找到链表的元素。这里用到了一个size的右移运算,size>>1表示size/2。首先判断index是在链表的前一半还是后一半,因为linkedList是双链表,可以往前和往后进行遍历。如果在前半部分就从首节点往后遍历,如果在后半部分就从最后一个节点往前遍历,这样最多遍历size的一半,避免遍历整个链表。

找到index对应的元素后执行linkedBefore方法

新建节点,节点pre就是succ的pre,节点的next就是succ。

将succ.pre指向新节点。

succ的pre为null,succ即为首节点,将first赋值给首节点

succ的pre不为空,则把succ的上一节点的next指向新节点

LinkedList,只有两种添加方式,一种是在列表最后添加(linkLast),一种是在列表某个元素前面添加 (linkBefore)。

LinkLast,首先创建一个新节点,节点pre指向最后一个节点,最后一个节点的next指向新节点。

LinkBefore,首先根据index下标获取到元素的位置,新建新节点,新节点的pre就是元素的pre,新节点的next就是该元素。元素的pre的next指向新元素。

LinkedList为何是双链表,链表主要缺点是查询速度很慢,添加或者删除都要找到要添加和删除的节点,而使用双链表,每次遍历循环前,都会判断一下索引是在链表的前半部分还是后半部分。如果是前半部分的话,从首部遍历到中间。如果是后半部分,从尾部遍历到中间。