1、首先我们需要了解的是ArrayList底层是基于数组实现的:根据索引定位元素快,增删需要做元素的移位操作。
1、创建ArrayList
首先是创建一个空的数组来存储相应的元素对象,并创建一个空数组,默认数组的长度我们设置为10;
//创建一个空的数组
transient Object[] elementData;
//数组中元素的个数
private int size;
//创建一个默认空数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//创建一个空数组
private static final Object[] EMPTY_ELEMENTDATA = {};
//定义数组的初始容量
private static final int DEFAULT_CAPACITY = 10;
当我们第一次创建ArrayList对象的时候会调用ArrayList中的无参构造器,这时我们数组的长度就会变成默认的十个长度
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
第二种创建方式:
有参构造器的创建,这个方法中传输了一个int类型的参数,就是你自己想定义的集合长度。当我们赋值进去后需要先判断这个数是否是大于0当大于0的时候我们就创建一个新的数组并把新的数组长度传给我们一开始定义的elementData;
如果传入的值等于0我们就把一个空数组传给elementDate因为可能有一些人需要创建空集合
其他的情况我们都抛出异常不予执行
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);
}
}
2、ArrayList中的扩容方法
我们先了解这个确认最后参数的方法;
当我们想要增加一个数组的时候我们需要传入一个值来,但是在这其中我们需要去判断我们的集合是否可以存入这个值所有我们就要与创建的elementDate相比较
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
首先传入一个需要扩容的值,我们将老的数组长度赋值给oldCapacity ,把后面oldCapacity + (oldCapacity >> 1)扩容的长度赋值给新的数组长度如果传进来的数组与我们扩容的长度还要长我们就把这个传进来数组的长度当作我们新数组的长度即可否则如果新的扩容长度大于想要的长度我们就把这个扩容后的数组长度穿回去继续接收元素。
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
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);
}
3、ArrayList中的增加方法
首先我们对数组进行判断看它是否可以存储一个新的元素就是前面说过的扩容方法的前奏。如果数组的长度不够我们将会进行扩容。扩容后我们就将数值穿进去并进行以这样的方式存储。
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
4、ArrayList中的删除方法
首先我们需要对传进来的元素进行对比
首先是用if语句判断是否为空因为空数组也是可以删除的,随后我们使用for循环一直遍历找到与传入的元素相等的集合元素并利用fastRemove进行删除。这个方法就是把要删除的元素的后面的所有元素想前移动以为并把这个数组赋值为空最后进行减少数组长度。
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
5、Array中的修改方法
修改方法中传入的值分别是索引值以及要修改的数据值
首先我们对索引进行判断是否符合集合的长度不符合就不进行修改
判断进入后我们对elementDate数组进行查询,查询找打后可以进行赋值到oldValue中,随后把elementDate在index上的元素值换成传入的参数中的元素。
public E set(int index, E element) {
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
6、ArrayList中的查找方法
此方法比较简单
只需要判断传入的索引值是否符合集合的长度,符合后我们就返回elementDate集合中index这个位置的元素 。
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
总结
ArrayList其中的使用原理还是数组,是通过数组来进行一些的操作,学习好前面的Java基础是为能看懂底层代码打好基础。