ArrayList初学

1、实例化ArrayList

看一下ArrayList的构造函数,有以下三种
public ArrayList(int initialCapacity)
public ArrayList()
public ArrayList(Collection c)

初始化过程中将会对elementData这个数组对象进行初始化,这个对象里面保存的就是ArrayList里面的数据。
其中第一个和第二个两个的区别就是是否指定ArrayList的初始化容量,如果未指定或者传入的initialCapacity=0,会将elementData赋值为一个空的Object[]数组,如下图所示:
这里写图片描述
这里的EMPTY_ELEMENTDATADEFAULTCAPACITY_EMPTY_ELEMENTDATA都是一样的东西。
第三个构造函数传入一个集合类型的对象,然后将c转换为数组,通过Arrays.copyOf 这个方法,将该数组赋值到elementData 对象中。

2、部分方法

trimToSize方法

该方法整理elementData对象,该对象由于是一个数组对象,它本身的大小是确定了的,在测试过程中,通过对ArrayList add值,会得到一个固定大小的elementData数组(默认为10),当我们add的值的个数小于数组长度的时候,该数组里面的值形式为[11, sss, addd, null, null, null, null, null, null, null],调用该方法过后,该数组将移除掉null对象。其中采用的方法仍然是Arrays.copyOf

add方法

当为传入添加元素的位置的时候,该方法内部将执行以下代码:

public boolean add(E e) {
    ensureCapacityInternal(size + 1); 
    elementData[size++] = e;
    return true;
}   
private void ensureCapacityInternal(int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    ensureExplicitCapacity(minCapacity);
}

private void ensureExplicitCapacity(int minCapacity) {
    modCount++;
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

这里写的就很明显了,添加的时候先判断当前elementData数组的长度是否大于传入的容量,如果小于就扩充elementData数组,扩充的算法为当前的长度+当前长度右移一位的长度。其中第一次添加的时候,会将默认的长度传入,这也就导致了就算ArrayList中就算只有一个对象,elementData的长度也会为10,如果想要将多余的长度去掉,则需要调用trimToSize方法。这里需要知道的是, elementData的长度是永远需要大于等于 ArrayList的个数的。
至于指定了添加位置的方法,则是调用 System.arraycopy这个方法,在指定位置后的数组元素向后移位。

    rangeCheckForAdd(index);

    ensureCapacityInternal(size + 1);  // Increments modCount!!
    System.arraycopy(elementData, index, elementData, index + 1,
                     size - index);
    elementData[index] = element;
    size++;
get,set方法
public E get(int index) {
    rangeCheck(index);

    return elementData(index);
}   
 public E set(int index, E element) {
    rangeCheck(index);

    E oldValue = elementData(index);
    elementData[index] = element;
    return oldValue;
}

get,set方法相对而言很好理解,先判断index是否在范围,然后返回(设置)elementData数组里面的相应元素

remove方法

当remove传入的index的时候,只需要将数组里面的元素删除即可。
当出入对象的时候,通过遍历整个数组,找到元素索引。通过fastRemove(index)方法进行删除。

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
}

和上面删除基本上是一样的,调用这个System.arraycopy这个方法,这个方法是个本地方法。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值