源码—ArrayList(JDK 1.8)

本文详细解析了ArrayList在JDK 1.8中的源码,包括属性、构造方法和重点方法如get、set、add、remove、indexOf等。分析了ArrayList的扩容机制,指出其初始容量、扩容策略。讨论了ArrayList与LinkedList的区别,涉及线程安全、数据结构、插入删除性能、内存占用等方面。同时,解释了RandomAccess接口的意义。最后,对比ArrayList和Vector,指出为何在多线程场景下使用Vector,而在单线程环境下更倾向于ArrayList。
摘要由CSDN通过智能技术生成

源码——ArrayList(JDK 1.8)

1. 属性

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
      
    //序列化id
    private static final long serialVersionUID = 8683452581122892189L;

    //默认初始化容量为10
    private static final int DEFAULT_CAPACITY = 10;	
   
    //指定容量为0时,返回该数组
    private static final Object[] EMPTY_ELEMENTDATA = {
   };
   
    /*
    	调用无参构造返回该数组。
    	它与EMPTY_ELEMENTDATA的区别就是:该数组是默认返回的,而EMPTY_ELEMENTDATA是在用户指定容量为0时返回。
    */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {
   };	
    
    /*
    	保存添加到ArrayList中的元素。 
		ArrayList的容量就是该数组的长度。 
		该值为DEFAULTCAPACITY_EMPTY_ELEMENTDATA 时,当第一次添加元素进入ArrayList中时,数组将扩容值DEFAULT_CAPACITY。 
		被标记为transient,在对象被序列化的时候不会被序列化。
    */
    transient Object[] elementData; // non-private to simplify nested class access

    //ArrayList的实际大小(数组包含的元素个数/实际数据的数量)默认为0
    private int size;
    
    /*
    	分派给arraylist的最大容量
		为什么要减去8呢?
		因为某些VM会在数组中保留一些头字,尝试分配这个最大存储容量,可能会导致array容量大于VM的limit,最终导致OutOfMemoryError。
    */
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
}

2. 构造方法

/*
	构造一个初始容量为10的空列表
	我们知道DEFAULTCAPACITY_EMPTY_ELEMENTDATA是一个空的Object[],将elementData初始化,elementData也是个Object[]类型。空的Object[]会给默认容量10。但是这里我们并没有看到数组的容量变为10啊,那么什么时候会被初始化为10的数组呢?答案是有元素被加入时(add方法).当进行第一次add的时候,elementData将会变成默认的长度:10。
*/
public ArrayList() {
   
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/*
	ArrayList(int initialCapacity):构造一个指定容量为capacity的空ArrayList。这是一个带初始容量大小的有参构造函数。
		初始容量大于0,实例化数组,将自定义的容量大小当成初始化elementData的大小
		初始容量等于0,将EMPTY_ELEMENTDATA赋给elementData
		初始容量小于0,抛异常
*/
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的构造方法就做一件事情:初始化数组,也即elementData

3. 重点方法

3.1 get()
//获取指定下标位置的元素
public E get(int index) {
   
    rangeCheck(index);	//越界检查
    return elementData(index);	//返回指定位置的元素
}


//越界检查
private void rangeCheck(int index) {
   
    if (index >= size)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}


//返回对应下标位置的元素
E elementData(int index) {
   
    return (E) elementData[index];
}
3.2 set()
//修改元素
public E set(int index, E element) {
   
    rangeCheck(index);	//越界检查

    E oldValue = elementData(index);	//记录旧值
    elementData[index] = element;	//新值替换旧值
    return oldValue;	//返回旧值
}
3.3 add()
//添加元素至数组的末尾
public boolean add(E e) 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值