java集合类源码详解-LinkedList(3)-基于JDK8

LinkedList的源码学习 再次继续,现在看add(int,E),这个方法是在指定位置插入元素,索引位起始是0

因为指定位置插入,需要遍历链表,所以时间复杂度为O(n)

写上测试代码,并且附上运行结果

点击dbug,点击下一步。 这里先检查索引位是否合法。

再次点击下一步。进入checkPositionIndex(),但是检查索引位是否合法,却是isPositionIndex()

再次点击下一步,这里的index必须比0 大 并且比size小,也就是说,可以插在第一个位置和 链表的末尾(也就是作为链表的最后一个元素),或者是在他们的中间。

 

再次点击下一步。这里开始进行逻辑判断,如果index==size 。说明是把这个节点附在链表的尾巴上,也就是末尾

linkLast()这个方法,之前已经看了。这里跳过

 

再次点击下一步,这里有和linkBefore()方法,还有个node()函数

 

再次点击下一步,进入node()方法。在node()方法里面,为了保证查找的效率,先对链表长度进行 除2.

然后在把除2后的值 跟index 这个索引比较,这样是为了提高查找效率。然后再遍历另外一半就行了。这个算法比较简单。

 

再次点击下一步。这里将 要插入的元素和 索引对应的节点传进linkBefore()方法

 

点击下一步,这里我们需要把这个索引位的节点的前一个节点的引用交给 pred变量保存。为什么要这样呢?因为我们需要在succ节点前插入新的节点,同时这还是一个双向链表,所以,我们得先保存下 succ节点的前一个节点的引用。

 

再次点击下一步,这里开始创建一个节点,这个新节点的前置节点是succ的前一个节点,后置节点是succ节点。这里我们把这个新创建的节点的引用也交给变量newNode保存。

 

点击下一步。

 

再次点击下一步,因为是双向链表,所以,我们这里也需要把newNode的引用给 succ.prev 也就是让succ指向这个新节点,双向链表

再次点击下一步。这里会判断,是否我们插入的是第一个位置,因为pred是succ的前置节点,如果succ是第一个节点,那么他的前置节点就是null。如果是null,说明我们要插入的是第一个节点,那么直接把头指针指向新节点就行了,这里这个判断肯定是false,我们继续点击下一步

 

点击下一步。这里就把pred的指向newNode,这个新节点就行了。

经过了这一系列操作,我们就把新节点和它前面,后面的节点 互相指向了,如此 就把这个节点添加到了这个双向链表中,那么最后size++,modcount++ ,就ok

 

好了,到这里,又学习完了一个 add()方法,后续将会继续学习 另外两个addAll()方法。

如果博客有什么问题请指出,大家一起学习进步。 

猜你喜欢

转载自blog.csdn.net/qq_37889257/article/details/84856404