ArrayList源码解读

一、 ArrayList概述:
ArrayList是基于数组实现的,是一个动态数组,所谓动态,就是它的容量会自动增加,ArrayList的初始容量是10。ArrayList不是线程安全的,ArrayList实现了Serializable接口,支持序列化。
二、 ArrayList的实现:
1、私有属性

private static final int DEFAULT_CAPACITY = 10;
//默认初始容量
private static final Object[] EMPTY_ELEMENTDATA = {};
//用于空实例的共享空数组实例
private transient Object[] elementData;
//elementData存储ArrayList内的元素
private int size;
//size表示ArrayList包含的元素的数量

2、构造方法

//使用初始容量构造一个空的ArrayList,容量为10;
public ArrayList() {
        super();
        this.elementData = EMPTY_ELEMENTDATA;
    }
//构造一个initialCapacity大小的ArrayList,当initialCapacity<0时,抛出IllegalArgumentException异常。
public ArrayList(int initialCapacity) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
    }
//构造一个包含指定collection的元素的列表,这些元素按照该collection的迭代器返回它们的顺序排列的
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);
    }

3、一些方法

// 用指定的元素替代此列表中指定位置上的元素,并返回以前位于该位置上的元素
public E set(int index, E element) {
        rangeCheck(index);
        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }
// 将指定的元素添加到此列表的尾部
public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
//将指定的元素插入此列表中的指定位置,如果当前位置有元素,则向右移动当前位于该位置的元素以及所有后续元素(将其索引加1)
public void add(int index, E element) {
        rangeCheckForAdd(index);
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,size - index);
        elementData[index] = element;
        size++;
    }
//按照指定collection的迭代器所返回的元素顺序,将该collection中的所有元素添加到此列表的尾部  
public boolean addAll(Collection<? extends E> c) {
        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacityInternal(size + numNew);  // Increments modCount
        System.arraycopy(a, 0, elementData, size, numNew);
        size += numNew;
        return numNew != 0;
    }
//从指定的位置开始,将指定collection中的所有元素插入到此列表中
public boolean addAll(int index, Collection<? extends E> c) {
        rangeCheckForAdd(index);
        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacityInternal(size + numNew);  // Increments modCount
        int numMoved = size - index;
        if (numMoved > 0)
            System.arraycopy(elementData, index, elementData, index + numNew,numMoved);
        System.arraycopy(a, 0, elementData, index, numNew);
        size += numNew;
        return numNew != 0;
    }
 // 返回此列表中指定位置上的元素  
public E get(int index) {  
        RangeCheck(index);  
        return (E) elementData[index];  
    }
// 移除此列表中指定位置上的元素
public E remove(int index) {
        rangeCheck(index);
        modCount++;
        E oldValue = elementData(index);
        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
        return oldValue;
    }
// 移除此列表中首次出现的指定元素(如果存在)。这是应为ArrayList中允许存放重复的元素。  
public boolean remove(Object o) {  
     // 由于ArrayList中允许存放null,因此下面通过两种情况来分别处理。  
     if (o == null) {  
         for (int index = 0; index < size; index++)  
             if (elementData[index] == null) {  
                 // 类似remove(int index),移除列表中指定位置上的元素。  
                 fastRemove(index);  
                 return true;  
             }  
     } else {  
         for (int index = 0; index < size; index++)  
             if (o.equals(elementData[index])) {  
                 fastRemove(index);  
                 return true;  
             }  
         }  
         return false;  
     } 
 }
//扩容时,会将原数组中的元素重新拷贝一份到新的数组中,每次数组容量的增长大约是其原容量的1.5倍。
//这种操作的代价是很高的,因此在实际使用时,我们应该尽量避免数组容量的扩张。
//当我们可预知要保存的元素的多少时,要在构造ArrayList实例时,就指定其容量,以避免数组扩容的发生。
//或者根据实际需求,通过调用ensureCapacity方法来手动增加ArrayList实例的容量。
public void ensureCapacity(int minCapacity) {
        int minExpand = (elementData != EMPTY_ELEMENTDATA)
            // any size if real element table
            ? 0
            // larger than default for empty table. It's already supposed to be
            // at default size.
            : DEFAULT_CAPACITY;

        if (minCapacity > minExpand) {
            ensureExplicitCapacity(minCapacity);
        }
    }
//删除Arraylist中所有元素,删除之后,剩下一个空的ArrayList
public void clear() {
        modCount++;
        // clear to let GC do its work
        for (int i = 0; i < size; i++)
            elementData[i] = null;
        size = 0;
    }

三、总结
1、关于ArrayList和Vector区别如下:
ArrayList在内存不够时默认是扩展50% + 1个,Vector是默认扩展1倍。
Vector提供indexOf(obj, start)接口,ArrayList没有。
Vector属于线程安全级别的,但是大多数情况下不使用Vector,因为线程安全需要更大的系统开销。
2、注意其三个不同的构造方法。无参构造方法构造的ArrayList的容量默认为10,带有Collection参数的构造方法,将Collection转化为数组赋

给ArrayList的实现数组elementData。
3、ArrayList的实现中大量地调用了Arrays.copyof()和System.arraycopy()方法。Arrays.copyof()实际上是在其内部又创建了一个长度为

newlength的数组,调用System.arraycopy()方法,将原来数组中的元素复制到了新的数组中。System.arraycopy()方法被标记了native,调用

了系统的C/C++代码,在JDK中是看不到的,但在openJDK中可以看到其源码。该函数实际上最终调用了C语言的memmove()函数,因此它可以保证

同一个数组内元素的正确复制和移动,比一般的复制方法的实现效率要高很多,很适合用来批量处理数组。Java强烈推荐在复制大量数组元素时

用该方法,以取得更高的效率。
4、ArrayList基于数组实现,可以通过下标索引直接查找到指定位置的元素,因此查找效率高,但每次插入或删除元素,就要大量地移动元素,

插入删除元素的效率低。
5、在查找给定元素索引值等的方法中,源码都将该元素的值分为null和不为null两种情况处理,ArrayList中允许元素为null。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值