Java巩固之路-----ArrayList

本文探讨了Java中ArrayList的工作原理,强调其底层基于数组的存储结构,导致其查询速度快但增删慢的特性。文章详细分析了ArrayList的主要操作,包括add元素(按位置和追加)、indexOf对象搜索、按位置和按对象删除元素的方法,还提到了动态扩容的必要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通过查看分析源码可以得知,ArrayList主要有如下几个成员变量:

//初始化arrayList的默认长度
private static final int DEFAULT_CAPACITY = 10;
//初始化有长度的arrayList,长度为0时的存储数组
private static final Object[] EMPTY_ELEMENTDATA = {};
//无参初始arrayList的默认存储的数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//arrayList存储数据的真正存储空间
transient Object[] elementData;
//当前元素的个数
private int size;

ArrayList的底层存储结构是数组,因为是数组,所以他的查询速度相比链表结构会更快,新增和删除元素的速度会慢于链表但是他需要连续存储空间,同时数组的大小也是固定,所以需要自己写函数来动态扩容。

ArrayList工作原理

add(E element)

//插入元素
//1、先判断size+1当前数组还能不能满足
public boolean add(E e) {
    ensureCapacityInternal(size + 1);  
    elementData[size++] = e;
    return true;
}
//2、判断是否是初次插入,是的话长度默认为10
private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
//3、数组进行加一位处理
private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
//动态扩容
//先将原来的长度动态扩容1.5倍。
//如果还是小于插入后长度,那就用插入后长度作为新的数组长度
//调用arrays.copy方法,将原数组复制到长度增加的新数组中
private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        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);
    }

add(int index, E element)

//1、数组下标判断
//2、动态扩容
//3、调用System.arraycopy方法,从数组下标位置到最后的所有元素全部向后复制一位
//4、将新元素插入到下标所在位置
public void add(int index, E element) {
        rangeCheckForAdd(index);

        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
    }

indexof(Object o)

//迭代数组,将数组元素依次与查询元素进行匹配,如果相同,返回下标。不存在,返回-1
public int indexOf(Object o) {
        if (o == null) {
            for (int i = 0; i < size; i++)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = 0; i < size; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

remove(int index)

//删除下标元素
//1、下标有效性判断
//2、计算需要移动的元素个数
//3、调用System.arraycopy方法,将数组从下标后一位元素到最后全部向前移动一位。
//4、将数组最后一位赋值为null。
public E remove(int index) {
        rangeCheck(index);

        modCount++;
        E oldValue = elementData(index);

        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }

remove(Object o)

//根据给定元素删除
//1、for循环查询元素所在下标
//2、使用下标快速删除元素
public boolean remove(Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值