Java 面试必考,Vector、ArrayList、LinkedList有何区别?

大家好,我是伍六七。

今天,阿七继续带大家来看一道经典面试题。对比 Vector、ArrayList、LinkedList 有何区别?你应该使用什么线程安全的集合框架?

让我们开始正文。

一、3 个角度对比 Vector、ArrayList、LinkedList

3.1 使用场景的区分:

  • Vector:线程安全,适用于多线程环境下的数据操作。
  • ArrayList:非线程安全,适用于单线程环境下的数据操作。
  • LinkedList:适用于频繁插入、删除操作的场景。

3.2 扩容操作和细节的区分:

  • Vector 和 ArrayList:在添加元素时,如果当前容量不足,会进行扩容操作。Vector 每次扩容会将容量翻倍,而 ArrayList 每次扩容会增加 50%的容量。扩容操作会导致数组重新分配内存,因此会影响性能。
  • LinkedList:在添加元素时,不需要进行扩容操作,因为它底层是链表结构,每个节点只需要记录前驱和后继节点的地址即可。

3.3 底层数据结构的区分:

  • Vector 和 ArrayList:底层数据结构都是数组,因此支持随机访问,时间复杂度为 O(1)。但是在插入和删除元素时,需要移动其他元素,时间复杂度为 O(n)。
  • LinkedList:底层数据结构是双向链表,因此不支持随机访问,只能通过遍历来访问元素。但是在插入和删除元素时,只需要修改前驱和后继节点的地址,时间复杂度为 O(1)。

总之,Vector、ArrayList、LinkedList 都是 Java 集合框架中常用的 List 实现类,它们各有优缺点,应根据具体场景选择合适的实现类。

如果需要高效的随机访问,可以选择 ArrayList;如果需要频繁的插入和删除操作,可以选择 LinkedList;如果需要线程安全,可以使用 Vector 嘛?

二、线程安全场景下,使用什么集合框架?

Vector 通过在方法上添加 synchronized 关键字来实现线程安全。

在 Vector 的方法中,使用了 synchronized 关键字来保证同一时间只有一个线程可以访问 Vector 的方法,从而避免了多线程并发访问时的数据竞争和不一致性。

尽管 Vector 可以提供线程安全的操作,但 Java 官方并不推荐使用 Vector,主要原因是使用 synchronized 锁住整个数组,会有很大的性能问题。

由于 Vector 的方法都是使用 synchronized 关键字修饰的,这会导致在多线程环境下性能较差。

因为每个线程在访问 Vector 的方法时都需要获得锁,这会导致其他线程阻塞等待,从而降低了并发性能。

如果不使用 Vector,可以使用以下方式来保证线程安全:

2.1 synchronizedList

使用 Collections 工具类的 synchronizedList 方法,将 ArrayList 转换为线程安全的 List:

ini 复制代码
List<String> list = Collections.synchronizedList(new ArrayList<>());

2.2 CopyOnWriteArrayList

使用 CopyOnWriteArrayList 类,它是 Java 并发包(java.util.concurrent)中提供的线程安全的 List 实现类:

ini 复制代码
List<String> list = new CopyOnWriteArrayList<>();

CopyOnWriteArrayList 在写操作时会创建一个新的数组,并将原数组的数据复制到新数组中,从而实现线程安全。由于读操作不需要加锁,因此读操作的性能较高,适用于读多写少的场景。

总之,尽管 Vector 可以提供线程安全的操作,但由于性能问题,Java 官方不推荐使用。可以使用 Collections 工具类的 synchronizedList 方法或者 CopyOnWriteArrayList 类来保证线程安全。具体选择哪种方式,应根据具体场景和需求来决定。

你学会了嘛?学会了点个赞再走~


关注我,送你全套我整理的 Java 岗位面试资料。这是我自己之前整理的面试题,靠着这份面试题,我从 30 人的小公司,进了 2000 人+的央企子公司,之后又进了互联网大厂。

一份让我进大厂&央企的面试题

相关推荐
星浩AI几秒前
让模型自己写 Skills——从素材到自动生成工作流
人工智能·后端·agent
华仔啊2 小时前
为啥不用 MP 的 saveOrUpdateBatch?MySQL 一条 SQL 批量增改才是最优解
java·后端
武子康3 小时前
大数据-242 离线数仓 - DataX 实战:MySQL 全量/增量导入 HDFS + Hive 分区(离线数仓 ODS
大数据·后端·apache hive
砍材农夫3 小时前
TCP和UDP区别
后端
千寻girling4 小时前
一份不可多得的 《 Django 》 零基础入门教程
后端·python·面试
SuperEugene4 小时前
Vue生态精选篇:Element Plus 的“企业后台常用组件”用法扫盲
前端·vue.js·面试
千寻girling4 小时前
Python 是用来做 AI 人工智能 的 , 不适合开发 Web 网站 | 《Web框架》
人工智能·后端·算法
Neptune14 小时前
JavaScript回归基本功之---类型判断--typeof篇
前端·javascript·面试
贾铭4 小时前
如何实现一个网页版的剪映(三)使用fabric.js绘制时间轴
前端·后端
xiaoye20184 小时前
Spring 自定义 Redis 超时:TTL、TTI 与 Pipeline 实战
后端