动态数组的实现-ArrayList

动态数组的实现-ArrayList

说完了LinkedList,来谈下另外一种常用的数组ArrayList。
这里写图片描述

可以看到他们同时实现了List接口,但是ArrayList和LinkedList的区别是LinkedList利用了双向链表的方法来进行创建,ArrayList利用了动态数组的方法,进行创建,类似于c中的动态数组申请。

从他们的创建方法也可以看出来,当数据较大时候,从中间插入,从头部插入,和在尾部插入的时候,他们的效率差距很大,同时查找也会存在很大的效率差异。

比如ArrayList是利用动态数组的方式,也就意味着如果我们在它头部插入的时候,他会将后面的所有的内容全部后移,而链表会在 判断过后 判断从头部还是尾部 进行遍历,同时插入数据,而且它的链表特性也不会将所有的数据向后移动。当两种数组在查找的时候,链表需要遍历,而数组可以通过数字进行查找,所以如果在数据很大的时候,在选择两种链表的时候,可以进行一番商酌。

构造函数

 public ArrayList(int initialCapacity) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
    }


    public ArrayList() {
        super();
        this.elementData = EMPTY_ELEMENTDATA;
    }


    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);
    }

这里可以看到他一共有三个构造函数,当不传入任何参数的时候,他会默认创建一个大小为EMPTY_ELEMENTDATA的数组,我们也可以通过指定大小进行指定大小的传入,当判断好数组大致大小过后,可以进行一个数组大小的生,可以避免后期的频繁的申请空间。
同样他也可以通过一个实现了collection的数组进行初始化。

addAll方法和申请数组大小函数

 public boolean addAll(Collection<? extends E> c) {  
   Object[] a = c.toArray();  
    int numNew = a.length;  
    ensureCapacity(size + numNew);      // Increments modCount  
    System.arraycopy(a, 0, elementData, size, numNew);  
    size += numNew;  
    return numNew != 0;  
 }

public void ensureCapacity(int minCapacity) {  
    modCount++;  
    int oldCapacity = elementData.length;  
    if (minCapacity > oldCapacity) {     //判断是否大于默认申请空间
        Object oldData[] = elementData;    
        int newCapacity = (oldCapacity * 3)/2 + 1;  //增加50%+1
            if (newCapacity < minCapacity)          //如果还是不够,直接让其等于最新的长度
                newCapacity = minCapacity;  
      // minCapacity is usually close to size, so this is a win:  
      elementData = Arrays.copyOf(elementData, newCapacity);       //新的数组
    }  
 }

照例来看一下addAll方法,ensureCapacityInternal判断当前的数字是否大于了申请的长度,如果空间不够了,在申请 1.5倍的空间,如果还是不够,直接让最新的长度等于需要的长度,然后将旧的数组给新的数组。

注意这里有一片代码片。

Object oldData[] = elementData;    

可能会问这个有什么作用,前面后面都没有用到它,但是这个在这里面确实也是起着它的作用,Arrays.copyOf将一个旧的数组赋值给新的数组,elementData 指向了一个新的引用,可能会在复制过程中被回收,elementData被回收了怎么办,这个时候创建一个Object oldData[] = elementData; ,将它们指向同一个引用,当数组被复制过后才会被回收,确保数组复制的完整性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值