目录

Java-数组与-List-浅析

Java 数组与 List 浅析

Java 数组与 List 浅析

目录


1. 数组(Array)

1.1 定义

  • 数组固定长度连续内存空间 存储 相同类型元素 的数据结构。
  • 特点
    • 长度不可变 :创建后无法动态扩容。
    • 内存连续 :支持快速随机访问(时间复杂度 O(1) )。
    • 类型固定 :所有元素类型必须一致(支持基本类型和对象类型)。

1.2 代码示例

int[] intArray = new int;          // 声明并初始化一个长度为5的int数组
String[] strArray = {"A", "B", "C"};  // 直接初始化字符串数组

2. 数组 vs List 的区别

特性数组List(列表)
长度可变性固定长度动态扩容
内存连续性连续内存逻辑连续,物理不一定连续
元素类型支持基本类型和对象类型仅支持对象类型(需装箱拆箱)
功能方法无内置方法(需手动实现)提供增删改查等丰富方法
线程安全部分实现类支持(如 Vector)

3. List 接口

3.1 定义

  • List 是 Java 集合框架中的接口,代表 有序、可重复 的元素集合。
  • 核心功能
    • 按索引访问元素( get(int index) )。
    • 动态增删元素( add() , remove() )。
    • 迭代遍历( iterator() )。

3.2 常见实现类

实现类特点
ArrayList基于动态数组实现,随机访问快,增删中间元素慢。
LinkedList基于双向链表实现,增删元素快(尤其是头尾),随机访问慢。
Vector线程安全的动态数组(已过时,建议用 CopyOnWriteArrayList 替代)。
CopyOnWriteArrayList线程安全,写操作时复制整个数组,读操作无锁。适合读多写少场景。

4. ArrayList vs LinkedList

4.1 核心区别

特性ArrayListLinkedList
底层数据结构动态数组双向链表
随机访问效率O(1)O(n)
头部插入/删除效率O(n) (需移动元素)O(1)
内存占用较低(仅存储数据)较高(每个节点存储两个指针)
适用场景高频随机访问,少增删高频增删,尤其是头尾操作

4.2 代码示例

// ArrayList 随机访问
List<Integer> arrayList = new ArrayList<>();
arrayList.add(1);
int value = arrayList.get(0);  // O(1)

// LinkedList 头部插入
List<Integer> linkedList = new LinkedList<>();
linkedList.add(0, 100);        // O(1)

5. 其他 List 实现类

5.1 Vector(已过时)

  • 特点 :线程安全的动态数组,方法通过 synchronized 实现同步。
  • 问题 :性能差,已被 CopyOnWriteArrayList 替代。

5.2 CopyOnWriteArrayList

  • 特点 :写操作时复制新数组,保证线程安全且读操作无锁。
  • 适用场景 :读多写少(如事件监听器列表)。

5.3 Stack(继承自 Vector)

  • 特点 :后进先出(LIFO)的栈结构。
  • 问题 :已不推荐使用,建议用 Deque 接口实现栈。

5.4 AbstractList 的定制实现

  • 可通过继承 AbstractList 实现自定义的 List 结构(如固定长度列表)。

6. 总结

6.1 数组 vs List

  • 数组 :简单、高效,适合固定长度和基本类型操作。
  • List :功能丰富,适合动态数据管理和复杂操作。

6.2 List 实现类选择

  • ArrayList :优先选择,适合大部分场景。
  • LinkedList :仅当需要高频头尾增删时使用。
  • CopyOnWriteArrayList :线程安全且读多写少时使用。
  • Vector/Stack :已过时,避免使用。

7. 附录代码

7.1 动态数组扩容(模拟 ArrayList)

public class CustomArrayList<T> {
    private Object[] data;
    private int size;
    private static final int DEFAULT_CAPACITY = 10;

    public CustomArrayList() {
        data = new Object[DEFAULT_CAPACITY];
        size = 0;
    }

    public void add(T element) {
        if (size == data.length) {
            // 扩容为原来的1.5倍
            int newCapacity = data.length + (data.length >> 1);
            data = Arrays.copyOf(data, newCapacity);
        }
        data[size++] = element;
    }
}

7.2 双向链表节点(模拟 LinkedList)

public class Node<T> {
    T item;
    Node<T> prev;
    Node<T> next;

    public Node(T item) {
        this.item = item;
    }
}