在 Java 集合框架中,ArrayList 和 LinkedList 是 List 接口的两个重要实现类,它们虽都满足 “有序、可重复、有索引” 的特性,但底层实现和适用场景差异显著。本文将解析两者的底层原理、核心特性及特有方法,帮助你在开发中合理选择。

一、ArrayList:基于动态数组的实现

底层原理

ArrayList 的底层是动态数组,其扩容机制是核心特点:

  1. 空参构造器初始化时,底层为长度 0 的数组;
  2. 添加第一个元素时,自动创建长度为 10 的数组;
  3. 数组存满后,触发扩容,新数组长度为原长度的 1.5 倍;
  4. 若一次添加多个元素导致 1.5 倍扩容仍不足,则直接以实际所需长度创建新数组。

核心特性

  • 查询快:通过索引直接访问元素(时间复杂度 O (1));
  • 增删慢:中间或头部增删元素时,需移动后续元素(时间复杂度 O (n));
  • 适合读多写少的场景,如数据查询、遍历操作。

二、LinkedList:基于双向链表的实现

底层原理

LinkedList 的底层是双向链表,每个元素(节点)包含前驱指针、数据域和后继指针,通过指针关联形成链式结构。

核心特性与特有方法

  • 查询慢:需从表头或表尾遍历至目标位置(时间复杂度 O (n));
  • 增删快:只需修改节点指针(中间元素增删时间复杂度 O (1),前提是找到节点);
  • 首尾操作高效:提供了直接操作首尾元素的特有 API,时间复杂度均为 O (1):
    • addFirst(E e):在链表头部插入元素;
    • addLast(E e):在链表尾部添加元素;
    • getFirst()/getLast():获取首尾元素;
    • removeFirst()/removeLast():移除并返回首尾元素。

适合增删频繁(尤其是首尾操作)的场景,如队列、栈的实现。

三、总结:如何选择?

  • 若需频繁查询或遍历,优先用ArrayList
  • 若需频繁在中间增删,或大量操作首尾元素,优先用LinkedList
  • 两者均为非线程安全,多线程环境需额外处理同步问题。

理解两者的底层差异,才能在实际开发中根据业务场景做出最优选择,提升程序性能。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐