![5b5ff7839c32ffdb57a489ae37c1bec3.png](https://img-blog.csdnimg.cn/img_convert/5b5ff7839c32ffdb57a489ae37c1bec3.png)
前言
从本章开始我会在必要的地方加上源码的注释翻译,方便大家从设计者的角度去读懂源码。
1.注释
/**
英文好的同学可以自己翻译一下,限于篇幅我这边简单的摘取一些关键点
这个类是一个 Doubly-linked list(双向链表),是继承了 List和 Deque两个接口的,并且允许元素为null 此实现类不是线程同步的,如果有多个线程同时使用该类,并且至少有一个线程对此类进行操作,那么就应该在外部进行强制同步操作;如果无法外部同步的话,那么为了保证线程安全则建议使用List list = Collections. synchronizedList(new LinkedList(...));这种方法来初始化; iterators(迭代器)的 fail-fast(快速失败)仅用于错误监测。关于快速失败,我会专门写一篇文章来介绍。
[1]Deque是一个双向队列,是继承Queue的一个结构,可以用作FIFO(先进先出),也可以用作LIFO(后进先出)堆栈,作为堆栈使用的时候是优先于旧的stack类使用的。
说到队列和栈,大家肯定就想到了经典的《如何用两个队列实现一个栈》哈哈哈哈哈
2. 源码
相较于ArrayList的对象数组的朴素形式,LinkedList则使用了双向链表这样的数据结构,带来的很大的区别就是,ArrayList更加擅长于查询,LinkedList更加擅长插入和删除。
既然他是一个链表结构,那么重点肯定就是他的结点Node<E>:
private
单单从这个结点我们自己就可以构想出
(1)自身的添加,删除,修改结点
(2)继承了双向队列的头部和尾部的添加和删除结点
public
(3)正向和反向的迭代器
//反向迭代器
(4)并行遍历迭代器
这个理念是java8新加进来的一种多线程遍历方式,ArrayList中也有。
//ArrayList
总结
ArrayList
- 基于数组,在数组中搜索和读取数据是很快的。因此 ArrayList 获取数据的时间复杂度是O(1);
- 但是添加、删除时该元素后面的所有元素都要移动,所以添加/删除数据效率不高;
- 每次达到阈值需要扩容,这个操作比较影响效率。
LinkedList
- 基于双端链表,添加/删除元素只会影响周围的两个节点,开销很低;
- 只能顺序遍历,无法按照索引获得元素,因此查询效率不高;
- 没有固定容量,不需要扩容;
- 需要更多的内存,如文章开头图片所示 LinkedList 每个节点中需要多存储前后节点的信息,占用空间更多些。
鉴于有杠精说ArrayList比LinkedList删除插入要快,并且给出了使用remove()方法去测试,我这边着重强调一下。
- 我们这边比较是从它们的数据结构层面去比较,单纯的去删除一个元素,很明显的是链表结构只需要挪动指针指向即可,而数组需要挪到元素位置后面的所有元素,快慢显而易见。但是你非要说我挪动数组的最后一个位置的数比指针快,那我无话可说。
- 单纯的删除一个元素意味着我们不是先找位置再删除,所以不要拿实际运行时间说话,实际中你要修改元素,首先肯定是得经过查询这一个步骤,那你比较的就是查询+删除的操作,有意义吗?
- 还有说现代CPU的缓存技术支持数组而不支持链表结构,那你去自己试验一下不就完了,然后大家可以和谐讨论,但是从数据结构删除这一层面,就事论事好吗?
- 最后我吐槽一下知乎,这个兄弟上来就“估计你没看过源码”,这种发言你还要我给他好脸色?我来知乎分享我的知识,有则改之无则加勉,上来就杠是你们知乎倡导的做法吗?
Java基础学习之Collection—List线程安全篇(Vector)
Java基础学习之Collection—List非线程安全篇(ArrayList )
参考
- ^Deque https://docs.oracle.com/javase/8/docs/api/java/util/Deque.html