面试题:Java 中的 List 接口有哪些实现类?

Java中的 List 接口有多个实现类,每个实现类都有其特定的使用场景和特性。以下是一些常见的 List 实现类:

  1. ArrayList
    • 基于动态数组的数据结构。
    • 支持对元素的快速随机访问(通过索引),因为它是基于数组实现的。
    • 在列表末尾添加元素的速度很快,但如果在列表中间或开头插入/删除元素,则需要移动其他元素,因此这些操作相对较慢。
    • 线程不安全。
  2. LinkedList
    • 基于双向链表的数据结构。
    • 对于在列表开头或结尾添加和删除元素的操作非常高效,因为不需要移动其他元素。
    • 不支持快速随机访问,因为要访问一个元素必须从列表的一端开始遍历直到找到目标元素。
    • 除了实现了 List 接口外,还实现了 Deque 接口,可以当作双端队列使用。
    • 线程不安全。
  3. Vector
    • 类似于 ArrayList,但是是同步的(线程安全)。
    • 性能上通常比 ArrayList 差,因为所有方法都是同步的。
    • 当不需要线程安全时,推荐使用 ArrayList 而不是 Vector
  4. Stack
    • 继承自 Vector,提供了后进先出(LIFO)数据结构的功能。
    • 提供了如 pushpoppeek 等方法用于栈的操作。
    • 主要用于需要堆栈行为的场合。
    • 线程安全,但由于继承自 Vector,所以性能可能不如预期。
  5. CopyOnWriteArrayList
    • 是 ArrayList 的一个线程安全变种,适用于读多写少的场景。
    • 每次修改(写操作,比如添加、移除元素)都会导致创建底层数组的一个新副本,然后将修改应用到副本上。
    • 由于这种特性,在迭代过程中不会抛出 ConcurrentModificationException,而且迭代器保证不会看到任何在迭代过程中发生的修改。
    • 写操作的开销较大,因为它涉及到数组复制;读操作则非常快,因为没有锁竞争。

根据具体的应用需求(如是否需要线程安全、主要操作是读还是写等),可以选择合适的 List 实现类。

例如,在单线程环境下且需要高效的随机访问时,选择 ArrayList 是比较合适的;而在多线程环境中并且主要是读操作的情况下,CopyOnWriteArrayList 可能是一个更好的选择。

THE END
喜欢就支持一下吧
点赞13 分享