Java ArrayList 详解

Java ArrayList 详解

ArrayList 是 Java 集合框架(Collection Framework)中最常用的类之一,是一种基于动态数组的数据结构,属于 List 接口的实现类。它允许存储重复的元素,有序,支持随机访问,且动态扩容。


1. ArrayList 的特点

  1. 有序ArrayList 按照元素插入的顺序存储,并按索引位置访问。
  2. 允许重复元素:可以存储重复值。
  3. 动态扩容:当容量不足时,会自动扩展存储空间。
  4. 随机访问:通过索引快速访问元素(时间复杂度 O(1))。
  5. 线程不安全ArrayList 不是线程安全的,多个线程同时修改需要手动同步。
  6. 实现接口:实现了 List 接口,同时支持 RandomAccessCloneableSerializable

2. ArrayList 的基本用法

2.1 创建与初始化
import java.util.ArrayList;

public class ArrayListExample {
    public static void main(String[] args) {
        // 创建空的 ArrayList
        ArrayList<String> list = new ArrayList<>();

        // 添加元素
        list.add("Apple");
        list.add("Banana");
        list.add("Cherry");

        // 输出列表
        System.out.println("List: " + list); // 输出: [Apple, Banana, Cherry]
    }
}
2.2 常用方法
import java.util.ArrayList;

public class ArrayListExample {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        
        // 添加元素
        list.add("A");
        list.add("B");
        list.add("C");

        // 获取元素
        System.out.println("Element at index 1: " + list.get(1)); // 输出: B

        // 修改元素
        list.set(1, "Z");
        System.out.println("After update: " + list); // 输出: [A, Z, C]

        // 删除元素
        list.remove("A");
        System.out.println("After removal: " + list); // 输出: [Z, C]

        // 检查是否包含
        System.out.println("Contains B? " + list.contains("B")); // 输出: false

        // 遍历
        for (String s : list) {
            System.out.println(s);
        }

        // 清空列表
        list.clear();
        System.out.println("Is empty? " + list.isEmpty()); // 输出: true
    }
}

3. ArrayList 的常用操作方法

方法描述
add(E e)在列表末尾添加元素。
add(int index, E element)在指定位置插入元素,原位置及后续元素右移。
remove(Object o)删除首次出现的指定元素。
remove(int index)删除指定索引位置的元素。
get(int index)获取指定索引位置的元素。
set(int index, E element)替换指定索引位置的元素为新的元素。
size()返回列表中元素的数量。
contains(Object o)检查列表中是否包含指定元素。
indexOf(Object o)返回元素的首次出现位置,若不存在则返回 -1。
lastIndexOf(Object o)返回元素最后一次出现的位置。
clear()清空列表中的所有元素。
isEmpty()检查列表是否为空。
toArray()将列表转换为数组。
addAll(Collection<? extends E>)添加另一个集合的所有元素到列表。
sort(Comparator<? super E>)对列表进行排序。

4. ArrayList 的工作原理

4.1 动态数组实现
  • 初始容量:创建时,如果未指定容量,ArrayList 默认初始容量为 10
  • 扩容机制:当存储的元素数量超过当前容量时,ArrayList 会动态扩容。扩容后的新容量为 原容量的 1.5 倍
  • 实现细节:底层通过数组 Object[] elementData 来存储元素。

扩容的实现代码:

private void grow(int minCapacity) {
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1); // 新容量 = 原容量 + 原容量的一半
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    elementData = Arrays.copyOf(elementData, newCapacity);
}
4.2 随机访问
  • 通过数组的索引访问,效率高,时间复杂度为 O(1)
4.3 插入和删除
  • 插入或删除会导致后续元素的移动,时间复杂度为 O(n)

5. ArrayList 的优缺点

5.1 优点
  1. 随机访问效率高:支持通过索引快速访问元素。
  2. 动态扩容:容量不足时自动扩展,无需手动调整。
  3. 实现了丰富的操作方法:提供增删改查、排序等常用操作。
5.2 缺点
  1. 插入和删除效率低:需要移动后续元素,尤其是在中间位置操作时。
  2. 线程不安全:在多线程环境中需要额外同步机制。
  3. 扩容成本高:扩容时需要分配新数组并拷贝旧数组的元素。

6. 线程安全的替代方案

6.1 Vector
  • Vector 是线程安全的 ArrayList 替代方案,但由于每个方法都进行同步,性能较低。
6.2 Collections.synchronizedList
  • 可以通过 Collections.synchronizedList 包装一个线程安全的 ArrayList
import java.util.*;

public class SynchronizedListExample {
    public static void main(String[] args) {
        List<String> list = Collections.synchronizedList(new ArrayList<>());

        list.add("A");
        list.add("B");

        synchronized (list) {
            for (String s : list) {
                System.out.println(s);
            }
        }
    }
}
6.3 CopyOnWriteArrayList
  • 在多线程环境中使用 CopyOnWriteArrayList,每次写操作都会创建新的副本,适用于读多写少的场景。

7. 常见问题与注意事项

  1. 越界异常

    • 尝试访问不存在的索引位置会抛出 IndexOutOfBoundsException
    list.get(10); // 若列表长度不足,抛异常
    
  2. 性能问题

    • 插入、删除操作在列表越靠后的位置,性能越高。
    • 遍历时,建议使用增强型 for 循环或迭代器。
  3. 多线程环境

    • ArrayList 是非线程安全的,多线程操作时需显式同步。

8. 总结

特性描述
实现结构动态数组,支持随机访问,扩容按 1.5 倍增长。
线程安全性非线程安全,需要显式同步或使用线程安全的替代方案。
性能读取效率高(O(1)),插入和删除效率低(O(n))。
适用场景适合需要频繁读取元素的场景,不适合高频插入或删除场景。

ArrayList 是 Java 中灵活且高效的动态数组实现,在开发中广泛应用于需要存储有序、可重复数据的场景。理解其特性和工作原理,合理使用它,能够显著提升程序的性能和可维护性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞滕人生TYF

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值