LinkedList是属于Sequence List,故遍历是用迭代器更快;

LinkedList继承自AbstractSequenceList、实现了List及Deque接口。其实AbstractSequenceList已经实现了List接口,这里标注出List只是更加清晰而已。AbstractSequenceList提供了List接口骨干性的实现以减少实现List接口的复杂度。Deque接口定义了双端队列的操作。

附上一张构造图(蓝色线条是继承,绿色线条是接口实现)如下:

其数据结构如下:

更清晰些:

说明:如上图所示,LinkedList底层使用的双向链表结构,有一个头结点和一个尾结点,双向链表意味着我们可以从头开始正向遍历,或者是从尾开始逆向遍历,并且可以针对头部和尾部进行相应的操作。

类的内部类:

说明:内部类Node就是实际的结点,用于存放实际元素的地方。

类的属性:

说明:LinkedList的属性非常简单,一个头结点、一个尾结点、一个表示链表中实际元素个数的变量。注意,头结点、尾结点都有transient关键字修饰,这也意味着在序列化时该域是不会序列化的。

LinkedList(Collection<? extends E>)型构造函数:

this();调用无参构造方法;  addAll(c);添加集合中的所有的元素:

说明:会调用无参构造函数,并且会把集合中所有的元素添加到LinkedList中。

核心函数分析:

说明:add函数用于向LinkedList中添加一个元素,并且添加到链表尾部。具体添加到尾部的逻辑是由linkLast函数完成的;

如下:

说明:对于添加一个元素至链表中会调用add方法 -> linkLast方法。

说明:参数中的index表示在索引下标为index的结点(实际上是第index + 1个结点)的前面插入。在addAll函数中,addAll函数中还会调用到node函数,get函数也会调用到node函数,此函数是根据索引下标找到该结点并返回,具体代码如下

说明:在根据索引查找结点时,会有一个小优化,结点在前半段则从头开始遍历,在后半段则从尾开始遍历,这样就保证了只需要遍历最多一半结点就可以找到指定索引的结点。

如上在调用remove移除结点时,会调用到unlink函数,unlink函数具体如下:

说明:将指定的结点从链表中断开,不再累赘。设为null后,GC机制会处理掉;

清空所有的方法:

需要将每个元素的item,next,prev都设为空;

前面linkLast()方法已经分析过了,其实同理;当理解双向链表结构,其实就很简单了;

总结:

有些说法认为LinkedList做插入和删除更快,这种说法其实是不准确的:

(1)LinkedList做插入、删除的时候,慢在寻址,快在只需要改变前后Entry的引用地址

(2)ArrayList做插入、删除的时候,慢在数组元素的批量copy,快在寻址

所以,如果待插入、删除的元素是在数据结构的前半段尤其是非常靠前的位置的时候,LinkedList的效率将大大快过ArrayList,因为ArrayList将批量copy大量的元素;越往后,对于LinkedList来说,因为它是双向链表,所以在第2个元素后面插入一个数据和在倒数第2个元素后面插入一个元素在效率上基本没有差别,但是ArrayList由于要批量copy的元素越来越少,操作速度必然追上乃至超过LinkedList。

从这个分析看出,如果你十分确定你插入、删除的元素是在前半段,那么就使用LinkedList;如果你十分确定你删除、删除的元素在比较靠后的位置,那么可以考虑使用ArrayList。如果你不能确定你要做的插入、删除是在哪儿呢?那还是建议你使用LinkedList吧,因为一来LinkedList整体插入、删除的执行效率比较稳定,没有ArrayList这种越往后越快的情况;二来插入元素的时候,弄得不好ArrayList就要进行一次扩容,记住,ArrayList底层数组扩容是一个既消耗时间又消耗空间的操作。

最新文章

  1. Java 设计模式 —— 单例模式
  2. PL/SQL通过存储过程为相同数据添加序号
  3. java 12 - 5 带有缓冲区的字符流
  4. Ajax请求ashx 返回 json 格式数据常见问题
  5. winform中文本框的一些案例
  6. OpenGL编程指南第版本学习笔记 --- OpenGL程序实现过程(win32 + OpenGL)
  7. js文件引用方式及其同步执行与异步执行
  8. 第六章:Python基础の反射与常用模块解密
  9. 长沙4月21日开发者大会暨.NET社区成立大会活动纪实
  10. Linux基本命令总结(四)
  11. 使用Ajax错误的全页面刷新问题
  12. 使用VirtualBox把IMG文件转换为VDI文件
  13. JAVA中执行JavaScript代码并获取返回值
  14. Mysql:性能优化
  15. Linux 下磁盘挂载
  16. 2018-2019-2 20175227张雪莹 《Java程序设计》 实验一 Java开发环境的熟悉
  17. xtrabackup备份mysql-3 差异备份
  18. STL vector简单用法
  19. Django中全局Context处理器
  20. binlog和redo log日志提交

热门文章

  1. shell编程:sed的选项
  2. springCloud的使用06-----分布式配置
  3. cmd中java的编译命令——java和javac、javap
  4. hashlib加密模块,加密方式:(MD5,sha级别)
  5. WPF的Effect效果
  6. Paint的Gradient的用法(转)
  7. git-window-install及常用命令
  8. Bootstrap 过渡效果
  9. Tmux 中开启鼠标选择与复制
  10. C# 使用猫拨打电话