从源码的角度简单理解 ArrayList 特性 (jdk 1.7,1.8)

先来说说ArrayList:

1.ArrayList实际上是通过一个数组去保存数据的,当我们构造ArrayList时,数组是没有初始化容量的。

2.当ArrayList 调用add方法的时候,会判断数据是否为空,如果为空,则初始化数组容量。长度为10.

3.ArrayList是线程不安全的。

4.当ArrayList容量不足以容纳全部元素时,ArrayList会自动扩张容量,新的容量 = 原始容量 + 原始容量 / 2(也就是自动扩容

5. ArrayList的克隆函数,即是将全部元素克隆到一个数组中.

好了下面我们把这4句还原回去源码中,这样就可以让我们加速记忆:

 

ArrayList实际上是通过一个数组去保存数据的,当我们构造ArrayList时,数组是没有初始化容量的。

从源码可以看出  

elementData 就是存储ArrayList的数组,从   DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};  可以看出 new ArrayList的时候是没有初始化的。
  transient Object[] elementData; // non-private to simplify nested class access

  private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};


  public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

当ArrayList 调用add方法的时候,会判断数据是否为空,如果为空,则初始化数组容量。长度为10.

当add方法进来后,会进入  ensureCapacityInternal 方法,然后再进入 calculateCapacity。然后判断当前数组为{},就会赋值

DEFAULT_CAPACITY 为初始化数组长度

 

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

private static final int DEFAULT_CAPACITY = 10;

transient Object[] elementData; // non-private to simplify nested class access

private int size;


 

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }


private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }


private static int calculateCapacity(Object[] elementData, int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        return Math.max(DEFAULT_CAPACITY, minCapacity);
     }
      return minCapacity;
    }

 

ArrayList是线程不安全的:

在源码中可以看出 add方法是没有用到锁,如果多线程的情况下,会到造成线程安全问题!

 

当ArrayList容量不足以容纳全部元素时,ArrayList会自动扩张容量,新的容量 = 原始容量 + 原始容量 / 2(也就是自动扩容)

从代码可以看出当  

minCapacity - elementData.length > 0 就调用 grow 方法。

minCapacity 当前要增加元素的位置,elementData.length 就是目前ArrayList 底层数组的容量,当

minCapacity  > elementData.length 时,就代表 ArrayList 容量不够 ,调用grow方法,实现自动扩容。

 

然后我们来看看grow方法的实现

int oldCapacity = elementData.length; 就是目前ArrayList的容量

重点就是  

oldCapacity >> 1    oldCapacity 向右移一位 就相当于 oldCapacity / 2  ,再加上本身。

所以

newCapacity   就是扩容后的数组容量大小

 ArrayList的克隆函数,即是将全部元素克隆到一个数组中

 

elementData = Arrays.copyOf(elementData, newCapacity); 这个就是把原始的数组克隆到另一个已经扩容过的数组上,具体代码就不贴了,大家不懂的话,可以自行百度下,这个API也是比较简单的

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值