ArrayList源码解析

来源:互联网 发布:org.apache.tools.ant 编辑:程序博客网 时间:2024/05/21 03:20

一、概述

ArrayList类提供了可调整大小的数组(动态数组),并实现了List接口。ArrayList类实现了所有可选的列表操作,并且允许所有元素,包括空值null。它提供了一些方法来操作内部用来存储​​列表的数组的大小。相较于LinkedList实现的常数因子较低。

二、功能

1、ArrayList 继承AbstractList,实现了List。它是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。

2、提供了随机访问功能。

3、可以通过元素的序号快速获取元素对象。

4、支持序列化,能通过序列化去传输。

5、能被克隆。

三、特点

1、随机访问速度快,插入、删除、移动性能较差。

2、支持null元素。

3、有序。

4、元素可以重复。

5、线程不安全。

四、为什么说ArrayList是线程不安全的?

1、线程安全

线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。

2、线程不安全

线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据。 

3、ArrayList是线程不安全的

private void ensureCapacityInternal(int minCapacity) {          if (elementData == EMPTY_ELEMENTDATA) {   //若elementData=={},则取minCapacity为默认容量和参数minCapacity之间的最大值               minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);          }            ensureExplicitCapacity(minCapacity);      } 
public boolean add(E e) {             ensureCapacityInternal(size + 1);  // Increments modCount!!   //确定ArrayList的容量大小         elementData[size++] = e;  //添加e到ArrayList中,然后size自增 1         return true;     } 

elementData[size++] = e,这条语句可拆分为两条:(1)elementData[size] = e;(2)size ++;
假设A线程执行完第一条语句时,CPU暂停执行A线程转而去执行B线程,此时ArrayList的size并没有加一,这时在ArrayList中B线程就会覆盖掉A线程赋的值,而此时,A线程和B线程先后执行size++,便会出现值为null的情况;若A线程在执行ensureCapacity(size+1)后没有继续执行,此时恰好minCapacity等于oldCapacity,B线程再去执行,同样由于minCapacity等于oldCapacity,ArrayList并没有增加长度,B线程可以继续执行赋值(elementData[size] = e)并size ++也执行了,此时,CPU又去执行A线程的赋值操作,由于size值加了1,size值大于了ArrayList的最大长度,因此便出现了ArrayIndexOutOfBoundsException异常。

五、源码解析

ArrayList继承AbstractList,实现List、RandomAccess、Cloneable、java.io.Serializable接口。

AbstractList提供了List接口的默认实现。 List接口定义了列表必须实现的方法。RandomAccess是一个标记接口,接口内没有定义任何内容。实现Cloneable接口的类,可以调用Object.clone方法返回该对象的浅拷贝。通过实现 java.io.Serializable 接口以启用其序列化功能,序列化接口没有方法或字段,仅用于标识可序列化的语义。

//ArrayList<E>说明支持泛型public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {    private static final long serialVersionUID = 8683452581122892189L;  //序列号    private static final int DEFAULT_CAPACITY = 10; //默认初始化容量    private static final Object[] EMPTY_ELEMENTDATA = {};  //空数组    private transient Object[] elementData;  //存储ArrayList内的元素;transient表示一个域不是该对象串行化的一部分,当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中    private int size;  //ArrayList的大小(包含的元素数量)
ArrayList构造方法(initialCapacity初始化elementData数组的大小)
public ArrayList(int initialCapacity) {   //initialCapacity为初始容量        super();        if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);//当初始容量非法时(小于0)抛出异常        this.elementData = new Object[initialCapacity];    }

ArrayList无参构造方法

public ArrayList() {          super();        this.elementData = EMPTY_ELEMENTDATA;  //创建一个空的ArrayList,此时其数组缓冲区elementData={},默认elementData初始容量为10    }

ArrayList构造方法,将提供的集合转成数组返回给elementData

public ArrayList(Collection<? extends E> c) {          elementData = c.toArray(); //返回包含c所有元素的数组        size = elementData.length;  //将转换后的Object[]长度赋值给当前ArrayList的size        // c.toArray might (incorrectly) not return Object[] (see 6260652)        if (elementData.getClass() != Object[].class)  //若c.toArray()返回的数组类型不是Object[],则利用 Arrays.copyOf()来构造一个大小为size的Object[]数组              elementData = Arrays.copyOf(elementData, size, Object[].class);  //复制指定数组    }

将当前容量值设为当前实际元素大小

public void trimToSize() {           modCount++;        if (size < elementData.length) {  //当实际大小<数组缓冲区大小            elementData = Arrays.copyOf(elementData, size);  //调整数组缓冲区 elementData,变为实际存储大小        }    }

将集合的capacit增加minCapacity

public void ensureCapacity(int minCapacity) {    //minCapacity为指定的最小容量        int minExpand = (elementData != EMPTY_ELEMENTDATA)  //最小扩充容量,默认为10            // 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) {  //若用户指定的最小容量>最小扩充容量,则以用户指定的为准,否则还是10            ensureExplicitCapacity(minCapacity);        }    }

明确 ArrarList 的容量

private void ensureCapacityInternal(int minCapacity) {        if (elementData == EMPTY_ELEMENTDATA) {   //若elementData=={},则取minCapacity为默认容量和参数minCapacity之间的最大值             minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);        }        ensureExplicitCapacity(minCapacity);    }

明确ArrayList的容量,用于内部优化,保证空间资源不被浪费

 private void ensureExplicitCapacity(int minCapacity) {        modCount++; // 将"修改统计数"+1,该变量主要是用来实现fail-fast机制的        // overflow-conscious code        if (minCapacity - elementData.length > 0) //确保指定的最小容量>数组缓冲区当前的长度,防止溢出代码            grow(minCapacity);    }
 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;  //数组缓冲区最大存储容量

获取该 list 所实际存储的元素个数

public int size() {          return size;    }

判断list是否为空

 public boolean isEmpty() {           return size == 0;       }

判断该 ArrayList是否包含Object类型对象

public boolean contains(Object o) {          return indexOf(o) >= 0;    }

顺序查找,返回元素的最低索引值

 public int indexOf(Object o) {          if (o == null) {            for (int i = 0; i < size; i++)  //顺序查找数组缓冲区                if (elementData[i]==null)                    return i;        } else {            for (int i = 0; i < size; i++)                if (o.equals(elementData[i]))                    return i;        }        return -1;    }

反向查找,返回元素的最高索引值

 public int lastIndexOf(Object o) {            if (o == null) {            for (int i = size-1; i >= 0; i--)  //逆序查找                if (elementData[i]==null)                    return i;        } else {            for (int i = size-1; i >= 0; i--)                if (o.equals(elementData[i]))                    return i;        }        return -1;    }

深度复制:对拷贝出来的ArrayList对象的操作,不会影响原来的ArrayList

Object 的clone()方法会复制本对象及其内所有基本类型成员和 String 类型成员,但不会复制对象成员、引用对象  

 public Object clone() {            try {            @SuppressWarnings("unchecked")                ArrayList<E> v = (ArrayList<E>) super.clone();            v.elementData = Arrays.copyOf(elementData, size); //对需要进行复制的引用变量,进行独立的拷贝            v.modCount = 0;            return v;        } catch (CloneNotSupportedException e) {            // this shouldn't happen, since we are Cloneable            throw new InternalError();        }    }

返回ArrayList的Object数组

 对返回的该数组进行操作,不会影响该 ArrayList

 public Object[] toArray() {          return Arrays.copyOf(elementData, size);    }

返回 ArrayList 元素组成的数组

 @SuppressWarnings("unchecked")    public <T> T[] toArray(T[] a) {   //a为需要存储 list 中元素的数组        if (a.length < size)  //若数组a的大小<ArrayList的长度,则将ArrayList全部拷贝到T[]中            // Make a new array of a's runtime type, but my contents:            return (T[]) Arrays.copyOf(elementData, size, a.getClass());        System.arraycopy(elementData, 0, a, 0, size);        if (a.length > size)  //若数组a的大小>ArrayList的长度,则将ArrayList的全部元素拷贝到数组a中            a[size] = null;        return a;    }

返回在索引为 index 的元素

  @SuppressWarnings("unchecked")    E elementData(int index) {           return (E) elementData[index];    }

获取指定位置的元素:从0开始计数

 public E get(int index) {          rangeCheck(index);        return elementData(index);    }

设置index位置元素的值

public E set(int index, E element) {          rangeCheck(index);   //设置 index 位置元素的值        E oldValue = elementData(index);        elementData[index] = element;        return oldValue;    }

向elementData中添加元素

 public boolean add(E e) {            ensureCapacityInternal(size + 1);  // Increments modCount!!   //确定ArrayList的容量大小        elementData[size++] = e;  //添加e到ArrayList中,然后size自增 1        return true;    }

在指定位置插入新元素,原先在index位置的值往后移动一位

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

移除指定索引位置的元素: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) {          if (o == null) {            for (int index = 0; index < size; index++)                if (elementData[index] == null) {  //判断是否存储了null                    fastRemove(index);                    return true;                }        } else {            for (int index = 0; index < size; index++)  //遍历ArrayList找到“元素o”,则删除,并返回true                if (o.equals(elementData[index])) {                    fastRemove(index);                    return true;                }        }        return false;    }

快速删除第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    }

清空所有存储元素,它会将数组缓冲区所以元素置为null

public void clear() {          modCount++;        // clear to let GC do its work        for (int i = 0; i < size; i++)            elementData[i] = null;        size = 0;    }

将一个集合的所有元素顺序添加到list末尾

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

从 index 位置开始,将集合 c 中的元素添加到ArrayList,并不会覆盖掉在index位置原有的值

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

删除fromIndex到toIndex之间的全部元素

protected void removeRange(int fromIndex, int toIndex) {          modCount++;        int numMoved = size - toIndex;        System.arraycopy(elementData, toIndex, elementData, fromIndex,numMoved);        // clear to let GC do its work        int newSize = size - (toIndex-fromIndex);        for (int i = newSize; i < size; i++) {            elementData[i] = null;        }        size = newSize;    }

提供给get()、remove()等方法检查给出的索引值 index 是否越界

private void rangeCheck(int index) {           if (index >= size)            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));    }

提供给add()和add()进行数组越界检查的方法

 private void rangeCheckForAdd(int index) {         if (index > size || index < 0)            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));    }

返回异常消息,用于传给IndexOutOfBoundsException

private String outOfBoundsMsg(int index) {          return "Index: "+index+", Size: "+size;    }

移除list中和c中共有的元素

public boolean removeAll(Collection<?> c) {         return batchRemove(c, false);    }

只保留list和集合c中公有的元素

 public boolean retainAll(Collection<?> c) {          return batchRemove(c, true);    }

批量删除

 private boolean batchRemove(Collection<?> c, boolean complement) {          final Object[] elementData = this.elementData;        int r = 0, w = 0;        boolean modified = false;        try {            for (; r < size; r++)                if (c.contains(elementData[r]) == complement)                    elementData[w++] = elementData[r];        } finally {            // Preserve behavioral compatibility with AbstractCollection,            // even if c.contains() throws.            if (r != size) {                System.arraycopy(elementData, r,                                 elementData, w,                                 size - r);                w += size - r;            }            if (w != size) {                // clear to let GC do its work                for (int i = w; i < size; i++)                    elementData[i] = null;                modCount += size - w;                size = w;                modified = true;            }        }        return modified;    }

序列化函数

 private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException{         // Write out element count, and any hidden stuff        int expectedModCount = modCount;        s.defaultWriteObject();        // Write out size as capacity for behavioural compatibility with clone()        s.writeInt(size);   //写入ArrayList大小        // Write out all elements in the proper order.        for (int i=0; i<size; i++) {   //写入存储的元素            s.writeObject(elementData[i]);        }        if (modCount != expectedModCount) {            throw new ConcurrentModificationException();        }    }


private void readObject(java.io.ObjectInputStream s)throws java.io.IOException, ClassNotFoundException {  //先将ArrayList的容量读出,然后将所有的元素值读出        elementData = EMPTY_ELEMENTDATA;        // Read in size, and any hidden stuff        s.defaultReadObject();        // Read in capacity        s.readInt(); // ignored   //从输入流中读取ArrayList的size        if (size > 0) {            // be like clone(), allocate array based upon size not capacity            ensureCapacityInternal(size);            Object[] a = elementData;            // Read in all elements in the proper order.            for (int i=0; i<size; i++) {   //从输入流中将所有的元素值读出                a[i] = s.readObject();            }        }    }

返回一个ListIterator

public ListIterator<E> listIterator(int index) {           if (index < 0 || index > size)throw new IndexOutOfBoundsException("Index: "+index);        return new ListItr(index);    }

返回一个Iterator迭代器,该迭代器是fail-fast机制的

 public Iterator<E> iterator() {         return new Itr();    }

 private class Itr implements Iterator<E> {        int cursor;       // index of next element to return  //下一个返回元素的索引,默认值为0          int lastRet = -1; // index of last element returned; -1 if no such  //上一个返回元素的索引,若没有上一个元素,则为-1        int expectedModCount = modCount;        public boolean hasNext() {  //是否有下一元素的判断            return cursor != size;        }        @SuppressWarnings("unchecked")        public E next() {            checkForComodification();            int i = cursor;  //指向游标当前位置            if (i >= size)                throw new NoSuchElementException();            Object[] elementData = ArrayList.this.elementData;            if (i >= elementData.length)                throw new ConcurrentModificationException();            cursor = i + 1;            return (E) elementData[lastRet = i];        }

ListItr继承Itr,实现ListIterator接口,可以进行双向移动,可以添加元素(有add()方法)

 private class ListItr extends Itr implements ListIterator<E> {          ListItr(int index) {  //指向下一个返回元素的索引位置            super();            cursor = index;        }

是否有上一个元素

 public boolean hasPrevious() {             return cursor != 0;        }

获取下一个元素的索引

 public int nextIndex() {              return cursor;        }

 获取 cursor 前一个元素的索引 

public int previousIndex() {              return cursor - 1;        }

返回 cursor 前一元素

 @SuppressWarnings("unchecked")        public E previous() {               checkForComodification();            int i = cursor - 1;            if (i < 0)                throw new NoSuchElementException();            Object[] elementData = ArrayList.this.elementData;            if (i >= elementData.length)                throw new ConcurrentModificationException();            cursor = i;            return (E) elementData[lastRet = i];        }
添加元素:在游标当前指向的索引位置插入一个元素
public void add(E e) {               checkForComodification();            try {                int i = cursor;                ArrayList.this.add(i, e);                cursor = i + 1;                lastRet = -1;                expectedModCount = modCount;            } catch (IndexOutOfBoundsException ex) {                throw new ConcurrentModificationException();            }        }    }

获取从fromIndex到toIndex之间的子集合

 public List<E> subList(int fromIndex, int toIndex) {          subListRangeCheck(fromIndex, toIndex, size);   //合法性检查        return new SubList(this, 0, fromIndex, toIndex);    }


  static void subListRangeCheck(int fromIndex, int toIndex, int size) {        if (fromIndex < 0)   //越界检查             throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);        if (toIndex > size)            throw new IndexOutOfBoundsException("toIndex = " + toIndex);        if (fromIndex > toIndex)  //非法参数检查            throw new IllegalArgumentException("fromIndex(" + fromIndex +                                               ") > toIndex(" + toIndex + ")");    }

嵌套内部类,继承AbstractList,实现RandomAccess接口

private class SubList extends AbstractList<E> implements RandomAccess {          private final AbstractList<E> parent;        private final int parentOffset;        private final int offset;        int size;        SubList(AbstractList<E> parent,                int offset, int fromIndex, int toIndex) {            this.parent = parent;            this.parentOffset = fromIndex;            this.offset = offset + fromIndex;            this.size = toIndex - fromIndex;            this.modCount = ArrayList.this.modCount;        }

设置新值,返回旧值

public E set(int index, E e) {             rangeCheck(index);            checkForComodification();            E oldValue = ArrayList.this.elementData(offset + index);            ArrayList.this.elementData[offset + index] = e;            return oldValue;        }
取值
 public E get(int index) {               rangeCheck(index);            checkForComodification();            return ArrayList.this.elementData(offset + index);        }

 添加元素

 public void add(int index, E e) {                rangeCheckForAdd(index);            checkForComodification();            parent.add(parentOffset + index, e);  //对子类添加元素,是直接操作父类添加的              this.modCount = parent.modCount;            this.size++;        }

删除元素

  public E remove(int index) {              rangeCheck(index);            checkForComodification();            E result = parent.remove(parentOffset + index);  //对子类删除元素,是直接操作父类删除的              this.modCount = parent.modCount;            this.size--;            return result;        }

 范围删除

 protected void removeRange(int fromIndex, int toIndex) {              checkForComodification();            parent.removeRange(parentOffset + fromIndex,                               parentOffset + toIndex);            this.modCount = parent.modCount;            this.size -= toIndex - fromIndex;        }

返回一个迭代器

public Iterator<E> iterator() {               return listIterator();        }









原创粉丝点击