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

LinkedList的学习 就重要的 又比较难的 就剩 ListItr 这个类了。

我们不写测试代码,直接到源码里面来看。

listIterator()这个方法,返回的就是ListItrt对象,调用ListItr()的有参构造 参数为index。

ListItr 总共有 四个变量,前三个节点从字面意思来看,相信都能理解。

再看看构造函数,这里有个三目运算符,看是否index==size。如果链表为空,又想遍历0号索引就会是true,next被赋为null,

如果 链表非空,但是索引位为 链表长度,那么是同样的。

这里我们假设正常情况,我们链表长度为3,index 为0 ,那么此时就会返回0号索引位的节点的引用 给next 变量,

也就是我们即将遍历的下一个节点。然后把 我们想要遍历的下一个索引 0 也赋给nextIndex 变量。

我们再看看hasNext()方法。只要下一个要遍历的索引位 比size 小 就返回true。这个很简单

 

最后再看看next()。这里先检查 modCount 是否与expectModCount 相等,因为我们马上要开始遍历链表了,所以

必须先确保没有 其他线程来对我们的 集合进行操作。然后通过hasNext()判断是否有下一个元素

next此时 是我们要开始遍历的元素,这里我们把它同 lastReturned 引用,为什么要这样,是因为lastReturned用来引用当前我们马上要遍历返回的节点,而next是代表要遍历的下一个节点,只要将此时next 引用的节点交给 lastReturned。然后next = next.next

next 就指向下一次要遍历的节点的,最后 nextIndex++, 然后返回lastReturned 这个引用的那个节点 保存的值就行了。

 

再看看hasPrevious()--这个方法是判断是否有前一个元素,这个太简单,如果nextIndex > 0 就返回true,因为我们链表的索引位是从0开始的。 只有0号索引位的前一个才是 小于0.

 

我们再看看 remove(),截图中的nextIndex()额previousIndex()太简单 我们直接跳过。

还是先执行 fail-fast 机制,然后看看是否当前要遍历的节点引用为null,如果是就抛异常。

我们把当前要遍历的节点的下一个节点用变量 lastNext保存。

然后调用我们之前学过的unlink()方法删除掉这个节点,这里可以看到 其实只要学了基本的 删除  增加 遍历 方法

其他的方法的实现 无非就是调用这几个方法。然后后面几句 就不再赘述了。

这两个方法 ,也没什么好看的。比较简单

 

现在 我们来看一些 剩下的 比较简单的 一些常用方法。

size()方法 特别简单  而且跟ArrayList 里面一模一样。

 

clear()方法 也很简单 

循环遍历 ,把节点的元素  ,next ,prev  都赋为null ,最后头尾指针都赋为null。最后size赋值为0,modCount++。

再来看看get()方法, 在ArrayList里面get()方法是很快的,它直接返回数据下标对应的数据就行了

而LinkedLsit 的get()方法也很简单,利用我们见了很多次的node()方法,然而node()方法是循环变量,效率很低

 

 

我们再看看,set()方法,set()方法是 值的更新

也很简单,先检查元素下标是否合法 返回去找到下标对象的节点,并拿到其引用,然后把这个节点的旧节点用变量保存

,因为方法结束要返回旧元素。然后我们把新元素 放进这个节点就可以了。这个也是设计到node()方法,效率很低。

 

再看看remove方法。其实调用的unlink()方法,这个方法我们学过了。

我们再看看

removeFirst()和removeLast()这两个方法 ,内部 也是调用我们学过的方法。很简单。

最后再看看contains(),查看这个list 里面是否有某个对象。这个方法套路和ArrayList一样,都是调用indexOf()

indexOf()也是一个循环遍历 ,也是很简单的。

好了,到这里LinkedList 我们就学习完毕了,总结一下,当LinkedList 对象的元素多了,凡是涉及到遍历的操作都不要做,

我们看到了,他的遍历都是循环的 从第一个节点开始 依次往后找,效率非常低。

猜你喜欢

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