java源码学习-ArrayList

1、 ArrayList类

1.1 继承 AbstractList
1.2 实现 List<E>, RandomAccess, Cloneable, java.io.Serializable 接口

2、 ArrayList类成员变量

1.1 private static final int DEFAULT_CAPACITY = 10;//默认初始化数组大小
1.2 private static final Object[] EMPTY_ELEMENTDATA = {};//共享的空数组对象
1.3 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//共享的默认空数组对象,与EMPTY_ELEMENTDATA的区别在于在添加元素的时候能否使用DEFAULT_CAPACITY的值进行扩容。
1.4 transient Object[] elementData;//元素存储的数组容器
1.5 private int size;//elementData中包含元素的个数

总结:
	成员变量都是私有的,也就是说ArrayList的子类不能直接使用这些属性值。
	存储元素的数组容器用transient修饰,即不参与序列化

3、 ArrayList类构造方法

1.1 public ArrayList(int initialCapacity)
	参数:初始化数组大小
	初始化逻辑:
	如果initialCapacity大于0,则创建一个initialCapacity大小的elementData数组
	如果initialCapacity等于0,则elementData为EMPTY_ELEMENTDATA
1.2 public ArrayList()
	初始化逻辑:
	elementData 为 DEFAULTCAPACITY_EMPTY_ELEMENTDATA
1.3  public ArrayList(Collection<? extends E> c) 
	参数:集合
	初始化逻辑:
	如果传入集合的大小不为0,则将集合转为数组,elementData指向该数组的引用。
	如果传入的集合的大小为0,则elementData为EMPTY_ELEMENTDATA

4、 ArrayList类核心方法

4.1 保证数据存储数组大小
1.1 private void ensureCapacityInternal(int minCapacity);
	参数:希望的最小数组容量
	逻辑:
		调用calculateCapacity方法计算最小数组容量。传入ensureExplicitCapacity中。
   		调用ensureExplicitCapacity方法,进行扩大存储数据的数组大小。
 1.2  private static int calculateCapacity(Object[] elementData, int minCapacity);
 	参数:当前数组对象elementData,希望的最小数组容量
 	逻辑:
 		如果当前数组对象是DEFAULTCAPACITY_EMPTY_ELEMENTDATA,则返回默认的数组容量大小DEFAULT_CAPACITY和希望的最小数组容量minCapacity中的最大值。
 		否则,返回希望的最小数组容量minCapacity。
 1.3 private void ensureExplicitCapacity(int minCapacity)
 	参数:希望的最小数组容量
	逻辑:
		如果希望的最小输入容量大小大于当前数组中元素的数量则扩容。否则不扩容。
 1.4 扩容方法分析
  private void grow(int minCapacity) {//传入希望的数组最小容量大小
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);//扩容的计算方法

		//如果扩充后的数组大小小于了希望的最小容量则使用希望额最小容量大小为当前扩容后的数组大小
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
         
        //扩容后的数组大小大于MAX_ARRAY_SIZE=Integer.MAX_VALUE-8,则数组新的容量为Integer.MAX_VALUE
        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);
    }

5、 总结

1、ArrayList当初始化时不为存储数据的数组初始化大小。为一个空数组。
2、当初始化时传入了希望最小数组容量为0或传入参数集合的个数为0时,添加数据时初始化数组容量为1。
   当初始化时不传参数时,添加数据时初始化数组的容量为默认容量10(即DEFAULT_CAPACITY)。
3、当数组满了的时候进行扩容。
4、ArrayList是线程不安全的。
5、数组扩容的方式是 oldCapacity + (oldCapacity >> 1)
6、首次添加元素是使用哪种方式进行初始化数组大小使用EMPTY_ELEMENTDATA和DEFAULTCAPACITY_EMPTY_ELEMENTDATA来区分。

该文章是在阅读源码的时候总结编写的,如果有不对的地方请大家多加指正。

猜你喜欢

转载自blog.csdn.net/shan_zhi_jun/article/details/82950626