一、Arraylist
ArrayList
类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。
ArrayList
继承了 AbstractList
,并实现了 List
接口。
二、LinkedList
LinkedList
既可以看作一个顺序容器,又可以看作一个队列(Queue
),同时又可以看作一个栈(stack
),LinkedList
底层通过双向链表实现,双向链表的每个节点用内部类Node
表示。LinkedList
通过first
和last
引用分别指向链表的第一个和最后一个元素。
LinkedList
继承自 AbstractSequentialList
,LinkedList
同时实现了List
接口和Deque
对口。
三、对比
1.底层结构
ArrayList
是基于数组实现的,ArrayList
类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。
LinkedList
是基于双向链表实现的,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。
2.性能
因为底层数据结构的不同,他们适用的场景不同,ArrayList
更适合随机查找,LinkedList
更适合删除和添加。
ArrayList
在新增和删除元素时,因为涉及到数组复制,所以效率比 LinkedList
低;
在遍历的时候,ArrayList
的效率要高于 LinkedList
。
3.线程安全
ArrayList
是基于动态数组实现的非线程安全的集合。当底层数组满的情况下还在继续添加的元素时,ArrayList
则会执行扩容机制扩大其数组长度。
ArrayList
查询速度非常快,使得它在实际开发中被广泛使用,但插入和删除元素较慢,同时它并不是线程安全的。
扩容机制:通过扩容机制判断原数组是否还有空间,若没有则重新实例化一个空间更大的新数组,把旧数组的数据拷贝到新数组中,先判断下标是否越界,再扩容。若插入的下标为i,则通过复制数组的方式将i后面的所有元素,往后移一位,新数据替换下标为i的旧元素。
LinkedList
是基于双向链表实现的非线程安全的集合,它是一个链表结构,不能像数组一样随机访问,必须是每个元素依次遍历直到找到元素为止。其结构的特殊性导致它查询数据慢。
查询时先判断元素是靠近头部,还是靠近尾部,然后再查询。
如果要使用线程安全的集合使用:
Vector
的数据结构和使用方法与ArrayList
差不多。最大的不同就是Vector
是线程安全的。几乎所有的对数据操作的方法都被synchronized
关键字修饰。synchronized
是线程同步的,当一个线程已经获得Vector
对象的锁时,其他线程必须等待直到该锁被释放。从这里就可以得知Vector
的性能要比ArrayList
低。
总结:
ArrayList
和LinkedList
都不是线程安全的,小并发量的情况下可以使用Vector
,若并发量很多,且读多写少可以考虑使用CopyOnWriteArrayList
。
因为CopyOnWriteArrayList
底层使用ReentrantLock
锁,比使用synchronized
关键字的Vector
能更好的处理锁竞争的问题。
4. 实现的接口
ArrayList
继承 AbstractList
类,实现 List
等接口。
LinkedList
继承 AbstractSequentialList
类,实现 List
和 Deque
等接口,因为 LinkedList
实现了 Deque
接口,所以LinkedList
还可以当作队列来使用。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/104932.html