ArrayList源码分析

该博客主要介绍了Java中的ArrayList,它是基于数组实现的集合类,线程不安全,多线程操作需额外同步。还对ArrayList进行了源码分析,包括类属性、三个构造方法,以及add、remove等核心方法和相关辅助方法。

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

一、ArrayList介绍

(1)ArrayList是基于数组实现的集合类。
(2)ArrayList是属于线程不安全集合,如果多线程对同一个ArrayList进行操作时,要额外进行同步操作。
(3)ArrayList的继承关系图

在这里插入图片描述

二、ArrayList源码分析

2.1 类属性

   //序列号
    private static final long serialVersionUID = 8683452581122892189L;

    //默认初始容量
    private static final int DEFAULT_CAPACITY = 10;
	
	
    //空的对象数组
    private static final Object[] EMPTY_ELEMENTDATA = {};

    //默认空对象数组
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    //存放集合元素的数组
    transient Object[] elementData;
	
	 //集合的大小(里面包含的元素)
    private int size;
	
	//能够分配的最大数组容量
	private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;




2.2 构造方法

ArrayList一共有三个构造方法:

在这里插入图片描述
(1)无参构造函数:


 /**
     * Constructs an empty list with an initial capacity of ten.
     *(构造一个空的list,初始容量是10)
     * ArrayList存放元素的其实就是数组elementData
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

(2)有参构造方法一:


/**
     * Constructs an empty list with the specified initial capacity.
     * (构造一个空的list,容量大小为给定参数大小)
     *
     * @param  initialCapacity  the initial capacity of the list
     * @throws IllegalArgumentException if the specified initial capacity
     *         is negative
     */
    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);
        }
    }


(3)有参构造方法二:

/**
     * Constructs a list containing the elements of the specified
     * collection, in the order they are returned by the collection's
     * iterator.
     *
     *(把一个集合里面的所有元素转移的当前ArrayList中)
     * @param c the collection whose elements are to be placed into this list
     * @throws NullPointerException if the specified collection is null
     */
    public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();//转换成数组
        if ((size = elementData.length) != 0) {
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }

2.3 核心方法
2.3.1 add方法


 /**
     * Appends the specified element to the end of this list.(把给定元素添加到list的末尾)
     *
     * @param e element to be appended to this list
     * @return <tt>true</tt> (as specified by {@link Collection#add})
     */
    public boolean add(E e) {

        //size为原来list里面元素的个数,因为添加了一个,所以要加 1,ensureCapacityInternal函数用来判断size+1这个大小数组还能不能放的下
        ensureCapacityInternal(size + 1);  // Increments modCount!!

        elementData[size++] = e;//在合适的位置插入元素,size+1
        return true;
    }
ensureCapacityInternal方法
  private void ensureCapacityInternal(int minCapacity) {

        //看当前数组是否为空的数组,如果是就把minCapacity设置为默认容量10
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }


ensureExplicitCapacity方法

rivate void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        //如果minCapacity大于数组长度,就说明数组的空间不够用了,就需要扩容
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);//关键的扩容函数
    }

grow方法


   /**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     *
     * @param minCapacity the desired minimum capacity
     */
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;//扩容前数组大小给oldCapacity,代表了旧的数组大小

        int newCapacity = oldCapacity + (oldCapacity >> 1); //对oldCapacity扩容1.5倍,然后给newCapacity,代表新的数组大小

        if (newCapacity - minCapacity < 0) //如果扩容后的新的数组大小还不足以放下minCapacity大小的元素,就让newCapacity等于minCapacity
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)//如果扩容后的新的数组大小比最大容量值还大,就调用hugeCapacity函数,把能给到的最大值给newCapacity
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);//容量确定好后就把数组里面的元素迁移复制过去
    }
2.3.2 remove方法

/**
     * Removes the element at the specified position in this list.
     * Shifts any subsequent elements to the left (subtracts one from their
     * indices).移除给定位置的元素,把剩余元素全体往左移动
     *
     * @param index the index of the element to be removed
     * @return the element that was removed from the list
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    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;
    }

removeAll方法


/**
     * Removes from this list all of its elements that are contained in the
     * specified collection.(从list里面移除集合c里面含有的元素)
     *
     * @param c collection containing elements to be removed from this list
     * @return {@code true} if this list changed as a result of the call
     * @throws ClassCastException if the class of an element of this list
     *         is incompatible with the specified collection
     * (<a href="Collection.html#optional-restrictions">optional</a>)
     * @throws NullPointerException if this list contains a null element and the
     *         specified collection does not permit null elements
     * (<a href="Collection.html#optional-restrictions">optional</a>),
     *         or if the specified collection is null
     * @see Collection#contains(Object)
     */
    public boolean removeAll(Collection<?> c) {

        Objects.requireNonNull(c);//检查集合c是否为空

        return batchRemove(c, false);//进行统一移除
    }
	
 private boolean batchRemove(Collection<?> c, boolean complement) {

        final Object[] elementData = this.elementData;//复制一份原始数据出来

        int r = 0, w = 0;

        boolean modified = false;

        try {
            for (; r < size; r++)//对数组进行遍历,检查集合c中的元素是否也出现在list里面(参数可为false与true)
                if (c.contains(elementData[r]) == complement)
                    elementData[w++] = elementData[r];
        } finally {
            // Preserve behavioral compatibility with AbstractCollection,
            // even if c.contains() throws.
            if (r != size) {//把符合要求的元素复制过去
                System.arraycopy(elementData, r,
                                 elementData, w,
                                 size - r);
                w += size - r;
            }
            if (w != size) {//把移动元素之后没用的元素清空,让垃圾回收器进行处理
                // clear to let GC do its work
                for (int i = w; i < size; i++)
                    elementData[i] = null;
                modCount += size - w;
                size = w;
                modified = true;
            }
        }
        return modified;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值