一直以来,ArrayList和LinkedList的区别,ArrayList和Vector的区别,List下不同实现类的相关知识点都是Java开发人员在开发过程中必须要掌握的基础知识,也是在面试过程中最常见的问题之一。
在这里,本文会将这些知识点加以整理,提取出最精华,最容易使用到的部分给大家,方便记忆。
List
List是一个继承于Collection的接口,ArrayList,LinkedList,Vector,Stack都只是它的一个实现类。
ArrayList
一个动态数组,由数组实现,所以具有数组的优缺点。方便快速随机访问,不适合频繁的添加或删除元素。
默认数组大小10。
扩容:底层采用线性连续空间存放元素,当空间不够时,会重新申请一片新的空间,大小是原来的1.5倍+1,并把原有的内容复制过去。
线程安全性:非线程安全
序列化:支持序列化,实现了java.io.Serializable接口
应用场景(以下两个条件同时满足)
- 需要快速随机访问元素
- 单线程场景或者多线程场景但是List只会被单线程操作
LinkedList
一个双向链表,具有链表的一些性质。包括能够快速添加和删除元素,但是不适合频繁访问元素,因为要从头指针开始遍历查找。
查找时,会根据index下标和整个List的长度size的关系,决定是从头查找还是从尾开始。如果index<size/2,则从头查找,否则从另一端开始遍历。
默认初始大小0。
扩容:底层实现是链表,不存在扩容问题。
线程安全性:非线程安全
应用场景:适用于需要快速插入和删除元素的场景
Vector
和ArrayList一样,都是由动态数组实现。方便快速随机访问,不适合频繁的添加或删除元素。
默认数组大小10。
扩容:与指定的增长系数有关,如果增长系数>0,则新的容量增长为原来的容量+增长系数,否则变为原来容量的2倍。
线程安全性:线程安全,函数大多数具有关键字synchronized,即都支持同步。
性能较差,因为方法加入了synchronized修饰,当执行的时候,系统会在方法前加一把锁,方法执行结束之后再释放掉。加锁和释放锁的过程会造成一定的系统开销,因此性能上要差许多。
序列化:不支持序列化
应用场景(以下两个条件同时满足)
- 需要快速随机访问元素
- 多线程场景且List会被多个线程操作
Stack
Stack是栈,继承于Vector。具有先进后出的特点。
对Vector进行扩展,添加了五个方法操作
- empty() 检查栈是否为空
- peek() 查看栈顶对象
- pop() 移除栈顶对象并返回
- push(E item) 压入栈顶
- search(Object o) 查找对象并返回其位置(下标值)
线程安全性:线程安全,由于继承于Vector,Vector是线程安全,故Stack也是线程安全类。
总结
有关List族群的相关知识点肯定不止以上这些,它的每一个实现类,都具有自己独特的性质,方便开发人员在不同的场景使用。
本文的内容只是帮助大家把这些实现类中比较重要的一些属性整理并记录下来,帮助大家快速记忆。如果大家希望能够了解更多的相关知识,可以自行上网查阅资料,也可以在文章最后留言,小编会在之后的文章中针对大家的需要整理成文,提供给大家~