List 相关方法底层实现原理
1:前言
我的所有文章的主要目的都是为了记录我的学习轨迹,写的不好,还希望各位大佬能够多多指教
2:概述

这篇文章主要讲解的是java的集合之一List集合的基本方法的底层原理,本篇文章主要堆LIst下的最经典的实现(ArrayList)来进行讲解,另一个很好的实现(vector)将在下一篇文章中进行讲解
ArrayList是一个动态数组,在真实的项目开发过程中,是最经常使用的List的实现,它允许任何元素的插入(包括NULL)
3:add()方法的具体实现原理
,因为ArrayList其是动态数组,所以当向一个list中添加元素的时候,都会去校验长度是否足够用于添加这个元素,如果当前的长度不足以添加这个元素,就会进行扩容操作。所以当我们使用ArraysList的时候,如果确定这个列表中存储元素的最大数量,最好指定一个初始化容量大小,避免过多的扩容操作,降低添加的效率。
接下来我们堆add()的具体实现来进行分析
1:
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
ensureCapacityInternal(size + 1); // Increments modCount!!
这一行代码的主要作用就是对列表的容量进行校验,也是我们主要进行研究的位置,进入校验列表容量的方法ensureCapacityInternal
private void ensureCapacityInternal(int minCapacity) {
// 对当前的列表判断是否为空如果为空,给当前列表初设置了一个最小的长度10
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
// 这个方法很重要,作用是用来判断当前列表是否需要扩容
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
// 用来判断是否需要扩容,当我们 new ArrayList的时候,很多人都以为始在创建这个对象的时候给List设置了一个初始化容量10,其实不是,真正给一个空的list设容量大小是通过第一次的扩容来实现的,
// 当数组容量小于最小容量10的时候就满足条件,需要扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
// 将老的数组长度右移
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
// 判断扩容到的长度是否超出java最大数值
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);
}
private static int hugeCapacity(int minCapacity) {
// 判断最小长度是否小于0(基本不可能)
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
// 将长度设置为最大值
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
get()方法
通过下标获取指定位置的元素,小标不存在,抛出IndexOutOfBoundsException异常
public E get(int index) {
// 校验索引位置是否存在
rangeCheck(index);
// 返回指定位置的数据
return elementData(index);
}