ArrayList源码解读

基于JDK1.7研究ArrayList的源码实现
源码学习的思路:
类的继承关系
存在的属性
默认值
类的构造函数
常用的方法源码解读

类的继承关系:
public class ArrayList extends AbstractList
implements List, RandomAccess, Cloneable, java.io.Serializable
继承自AbstractList,对Collection接口中的部分方法做了实现
实现了List接口,List接口中的方法都需要在ArrayList中进行实现
实现了RandomAccess、Cloneable、java.io.Serializable可以实现克隆,可以实现序列化、反序列化

类中存在的属性:
数据在ArrayList中存储在该elementData,其是一个数组
private Object[] elementData;

存储的是数据的个数
private int size;
ArrayList底层使用的是数组的存储结构

默认值:
//默认的数组大小是10
DEFAULT_CAPACITY = 10

类的构造函数

有参构造:参数:表示执行初始数组容量
public ArrayList(int initialCapacity) {
参数校验合法性
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
对属性elementData做初始化处理
this.elementData = new Object[initialCapacity];
}

默认的无参构造函数
public ArrayList() {
super();
this.elementData = EMPTY_ELEMENTDATA;
}

有参构造函数:(通过一个集合实例实例化ArrayList) 参数:Collection集合下的实例来实例化ArrayList集合
public ArrayList(Collection<? extends E> c) {
   将集合转化为数组类型
    elementData = c.toArray();
    size = elementData.length;
    // c.toArray might (incorrectly) not return Object[] (see 6260652)
    if (elementData.getClass() != Object[].class)
        elementData = Arrays.copyOf(elementData, size, Object[].class);
}

常用的方法源码解读
添加元素:add()
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}

private void ensureCapacityInternal(int minCapacity) {
if (elementData == EMPTY_ELEMENTDATA) {
//数组未做初始化时会进入该操作,获取初始容量:10
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}

       ensureExplicitCapacity(minCapacity);

}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;

      // overflow-conscious code
      if (minCapacity - elementData.length > 0)
          考虑扩容
          grow(minCapacity);

}

扩容时机:数组存储数据的个数(size+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);
}

数组的扩容是按照原数组长度的1.5倍扩容

添加元素的过程:
1、考虑扩容
当存储数据个数(size)大于数组长度(elementData.length),进行扩容
按照原数组的1.5倍进行扩容,(新建数组,将原数据拷贝到新数组上,并使elementData指向新数组)
2、将数据插入到最后的位置(size)
3、对计数的size进行加1操作

获取元素:get(int index)
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];
}

删除元素:remove()
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;
}

删除操作过程:
从数组0号位置往后遍历,判断是否是否存在(null使用==,非null值使用equals判断相等)
存在则直接删除,将后续数据前移一位,最后一位数据置为null,
若数据重复只删除第一次出现的数据

指定位置的数据删除操作
将该位置之后的数据前移一位,将最后的数据置为null
private void fastRemove(int index) {
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[–size] = null; // clear to let GC do its work
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值