Arraylist翻译分析

本文详细分析了 Java 中 ArrayList 类的实现,包括构造器、容量调整、添加与删除元素、扩容机制等方面,深入理解 ArrayList 的内部工作原理。
摘要由CSDN通过智能技术生成

public class ArrayList<E> extends AbstractList<E>

        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

{      //序列号UID,代表版本,私有的静态常量

    private static final long serialVersionUID = 8683452581122892189L;

 

    /**

     *定义数组初始化默认长度为10,静态常量

     */

    private static final int DEFAULT_CAPACITY = 10;

 

    /**

     *用于空实例的数组,静态私有的,空实例意味着创建时为,空,

       *类型为object(相当于泛型,即任何类型都可以)

   */

    private static final Object[] EMPTY_ELEMENTDATA = {};

 

    /**

     * 用于默认大小的空实例的共享空数组实例。我们

将其与EMPTY_ELEMENTDATA区分开来,以便知道何时膨胀多少

添加第一个元素。

静态私有数组对象常量    

 */

    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

 

    /**

     * 存储ArrayList元素的数组缓冲区。

ArrayList的容量是这个数组缓冲区的长度。任何

空ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA

当添加第一个元素时是否扩展为DEFAULT_CAPACITY     */

    transient Object[] elementData; // non-private to simplify nested class access

 

    /**

     * ArrayList的大小(包含的元素数量)。

       *  私有的int类型,默认为0

     *

     * @serial

     */

    private int size;

 

    /**

     * 构造器

     *

     * @param  initialCapacity  参数initialCapacity为arraylist容量

     * @throws  如果参数容量为负数,则抛出异常IllegalArgumentException

//如果传递的参数长度>0,给数组缓冲区赋值长度,长度为传递的参数长度

//如果传递参数长度为0,将empty_elementdata这个空数组给elemendata

//如果传递参数小于0,将抛出IllegalArgumentException,这个异常

 

     */

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);

        }

    }

 

    /**

     *无参构造,这个arraylist的初始长度为10

     */

    public ArrayList() {

        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;

    }

 

    /**

     * 构造一个包含指定集合元素的列表,按照集合的迭代器返回元素的顺序     *

     * @param 参数是个集合。集合中包括要将其元素放置到arraylist中

     * @throws如果指定传递参数的集合元素为空,则抛出空指针异常

//1.调用collection的toArray方法,但是因为collection是接口,其实就是相当于调用传递进来的参数的toArray方法,toArray方法的目的返回包含此集合中所有元素的数组。

如果此集合保证其迭代器返回元素的顺序,则此方法必须以相同的顺序返回元素。

返回的数组将是“安全的”,因为这个集合不维护对它的引用。(换句话说,这个方法必须分配一个新的数组,即使这个集合由一个数组支持)。因此,调用者可以自由地修改返回的数组。

此方法充当基于数组和基于集合之间的桥梁

2.然后集合容器转换为数组之后,再赋值给elementData

3.将elemendata的长度赋值给size,再把size属性进行判断

4. c.toArray 被重写可能返回的有可能不返回一个 Object 数组,所以需要进行类型匹配判断

例如:

String.class 是能对类名的引用取得在内存中该类型class对象的引用,而new String().getClass() 是通过实例对象取得在内存中该实际类型class对象的引用

5.如果类型不一致,调用Arrays.copyof进行复制操作,底层调用本地方法system.copyof

,然后返回一个泛型数组,再将这个泛型数组赋值给elementData,即地址赋值,注意这里的elementdata属性不是私有的,也不是常量

6.如果类型一致,直接将elemendata赋值给EMPTY_ELEMENTDATA;

 

     */

public ArrayList(Collection<? extends E> c) {

        elementData = c.toArray();

        if ((size = elementData.length) != 0) {

         

            if (elementData.getClass() != Object[].class)

                elementData = Arrays.copyOf(elementData, size, Object[].class);

        } else {

            // replace with empty array.

            this.elementData = EMPTY_ELEMENTDATA;

        }

    }

 

    /**

     * 1.将这个<tt>ArrayList</tt>实例的容量调整为列表的当前大小。应用程序可以使用这个操作来最小化<tt>ArrayList</tt>实例的存储。

Mount是AbstractList中的,由迭代器和列表迭代器使用,目的是为了防止属性意外的改变. 如果这个字段的值意外变化,迭代器(或列表迭代器)将抛出一个{@code ConcurrentModificationException}来响应{@code next}, {@code remove}, {@code previous},提供了快速的故障行为,而不是在迭代期间面对并发修改时的非确定性行为。

2.判断size和缓冲长度的大小,如果size小于缓冲数组的长度,再判断size是否等于0,如果size等于0,则返回EMPTY_ELEMENTDATA,否则就用Arrays.copyof对elementada进行自我复制,新的elementdata的长度为实际有效个数size

     */

    public void trimToSize() {

        modCount++;

        if (size < elementData.length) {

            elementData = (size == 0)

              ? EMPTY_ELEMENTDATA

              : Arrays.copyOf(elementData, size);

        }

    }

 

    /**

     *如果需要,增加这个<tt>ArrayList</tt>实例的容量,以确保它至少可以容纳最小容量参数指定的元素数量。     *

     * @param   minCapacity   描绘期望的最小容量

       1.先定义一个最小期望

2.判断elementdata是否等于默认大小的空实例的共享空数组实例

       3.如果等于,则返回0给最小期望,如果不等于,则返回10给最小期望

       4.再判断传递进来的形参和最小期望的关系

       5.如果形参大于最小期望,调用ensureExplicitCapacity方法,此时把接收的minCapacity继续当作形参传给ensureExplicitCapacity

     */

    public void ensureCapacity(int minCapacity) {

        int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)

            // any size if not default element table

            ? 0

            // larger than default for default empty table. It's already

            // supposed to be at default size.

            : DEFAULT_CAPACITY;

 

        if (minCapacity > minExpand) {

            ensureExplicitCapacity(minCapacity);

        }

    }

       //定义私有的静态方法calculateCapacity,计算出实际长度,该方法形参为elementData和传入的最小长度,如果传递的elementData地址等于默认共享数组的地址,返回传入最小长度和10之中的最大值,如果地址不等,返回传入的最小长度

    private static int calculateCapacity(Object[] elementData, int minCapacity) {

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值