关于LinkedList的详细阐述( 二 )
从源码中我们可以了解到 , 链表结构的节点新增、删除都非常简单 , 仅仅把前后节点的指向修改下就好了 , 所以 LinkedList 新增和删除速度很快 。
2.3 查询节点在链表查询某一个节点是比较慢的 , 因为需要挨个循环查找才行 , 我们看看 LinkedList 的源码是如何寻找节点的:
// 根据链表索引位置查询节点Node
从源码中我们可以发现 , LinkedList 并没有采用从头循环到尾的做法 , 而是采取了简单二分法 , 首先看看 index 是在链表的前半部分 , 还是后半部分 。 如果是前半部分 , 就从头开始寻找 , 反之亦然 。 通过这种方式 , 使循环的次数至少降低了一半 , 提高了查找的性能 , 这种思想值得我们借鉴 。
2.4 迭代器【关于LinkedList的详细阐述】因为 LinkedList 要实现双向的迭代访问 , 所以我们使用 Iterator 接口肯定不行了 , 因为 Iterator 只支持从头到尾的访问 。 Java 新增了一个迭代接口 , 叫做:ListIterator , 这个接口提供了向前和向后的迭代方法 , 如下所示:
data-draft-node="block" data-draft-type="table" data-size="normal" data-row-style="normal">
迭代顺序方法
LinkedList 实现了 ListIterator 接口 , 如下图所示:
// 双向迭代器private class ListItr implements ListIterator
我们先来看下从头到尾方向的迭代:
// 判断还有没有下一个元素public boolean hasNext() {return nextIndex < size;// 下一个节点的索引小于链表的大小 , 就有}?// 取下一个元素public E next() {//检查期望版本号有无发生变化checkForComodification();if (!hasNext())//再次检查throw new NoSuchElementException();// next 是当前节点 , 在上一次执行 next() 方法时被赋值的 。// 第一次执行时 , 是在初始化迭代器的时候 , next 被赋值的lastReturned = next;// next 是下一个节点了 , 为下次迭代做准备next = next.next;nextIndex++;return lastReturned.item;}
上述源码的思路就是直接取当前节点的下一个节点 , 而从尾到头迭代稍微复杂一点 , 如下:
// 如果上次节点索引位置大于 0 , 就还有节点可以迭代public boolean hasPrevious() {return nextIndex > 0;}// 取前一个节点public E previous() {checkForComodification();if (!hasPrevious())throw new NoSuchElementException();// next 为空场景:1:说明是第一次迭代 , 取尾节点(last);2:上一次操作把尾节点删除掉了// next 不为空场景:说明已经发生过迭代了 , 直接取前一个节点即可(next.prev)lastReturned = next = (next == null) ? last : next.prev;// 索引位置变化nextIndex--;return lastReturned.item;}
推荐阅读
- 高下立现!关于核心技术的态度,柳传志和任正非截然不同
- 关于手机的谣言……别再信了
- 这次真不站华为!关于华为下架腾讯游戏事件!华为有点不够意思
- 关于特斯拉副总裁陶琳女士回应的回应
- 关于小米11“环保”,是我们低估了雷军,还是小米高估了人性?
- 小米11正式发布,关于送不送充电器,雷军给出了一个“神奇”的方案
- 关于销售破万的华为新机!原来罗永浩曾经的话,还真的没有说错
- 关于5G手机的5个伪真相,别再继续被人骗下去了
- AirPods Max是如何低功耗运作的,来看详细说明
- 超好用的UnixLinux 命令技巧 大神为你详细解读