ArrayList数据结构数组

在Java中,ArrayList 是一种基于数组实现的数据结构,它是 List 接口的一个常用实现。ArrayList 提供了动态数组的功能,可以在运行时动态地调整数组的大小。以下是对 ArrayList 的源码分析和使用示例。

基本数据结构

ArrayList 的内部数据结构基本上是一个数组。在Java的 ArrayList 类中,这个数组是用 Object[] 类型定义的,可以容纳任何类型的对象。

关键属性

ArrayList 主要有如下几个关键属性:

  1. Object[] elementData:这是存储ArrayList元素的数组。
  2. int size:表示ArrayList中实际存储的元素数量。

构造函数

ArrayList 提供几个构造函数,最常用的有:

  • ArrayList():创建一个空列表。
  • ArrayList(int initialCapacity):创建一个具有指定初始容量的空列表。
  • ArrayList(Collection<? extends E> c):创建一个包含指定集合的元素的列表。

动态扩容

当向 ArrayList 添加元素时,如果内部数组已满,就需要进行扩容。默认情况下,每次扩容会增长50%的容量。

源码解析(部分)

以下代码是ArrayList的一部分简化版本,用于展示动态扩容的逻辑:

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
    private static final int DEFAULT_CAPACITY = 10; // 默认的数组大小
    private static final Object[] EMPTY_ELEMENTDATA = {};

    transient Object[] elementData; // 存储ArrayList元素的数组
    private int size; // ArrayList中元素的个数

    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
        }
    }

    public boolean add(E e) {
        ensureCapacityInternal(size + 1); // 确保容量
        elementData[size++] = e;
        return true;
    }

    private void ensureCapacityInternal(int minCapacity) {
        if (elementData == EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        if (minCapacity - elementData.length > 0) {
            grow(minCapacity);
        }
    }

    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1); // 增长50%
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
}

代码演示

以下是如何使用 ArrayList 的一个简单示例:

import java.util.ArrayList;

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

        list.add("Apple");
        list.add("Banana");
        list.add("Cherry");

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

        // 获取元素
        String item = list.get(1);
        System.out.println("The second fruit is: " + item);

        // 数组大小
        int size = list.size();
        System.out.println("The size of the list is: " + size);

        // 删除元素
        list.remove("Banana");
        System.out.println("After removal: " + list);
    }
}

细节详尽

一些重要的点需要注意:

  1. 线程不安全ArrayList 不是线程安全的。如果多线程环境中需要使用 ArrayList,则必须通过外部方法来同步访问。

  2. 快速失败迭代器ArrayList 的迭代器是快速失败的,即在迭代过程中如果集合被修改了,则会抛出 ConcurrentModificationException

  3. 空间复杂度ArrayList 有可能持有比其实际元素数量更多的内存,因为它可能会预留额外的空间以减少扩容操作。

通过这样深入、详尽的解析和代码示例,我们可以全面地理解 ArrayList 的工作原理和使用方式,并在实际编程中根据需要做出合适的选择。

  • 17
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

辞暮尔尔-烟火年年

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

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

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

打赏作者

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

抵扣说明:

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

余额充值