JDK 1.7源码阅读笔记(二)集合类之ArrayList

本文深入剖析了Java中ArrayList的源码实现,详细介绍了其内部结构、容量调整策略、增删查改操作的时间复杂度及线程安全性。适用于希望深入了解ArrayList工作原理的开发者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  ArrayList是我们在java编程中经常使用的类,如何能更好的掌握并使用一个数据结构,个人感觉还是需要研读它的源码,在理解源码的基础上加以应用,才可以明白所以然,明白为什么要这样用。

前言

  ArrayList源码还是较长的,所以索性把阅读源码的感悟写到前面,关于源码那部分只是作为一个备份,如果有童鞋对ArrayList源码感兴趣,那么可以慢慢看后面的源码,我把自己对于源码的理解写到源码里了!如果有不正确的地方,还希望有牛人指正,多谢多谢!
  小小总结:
  (1)ArrayList是List 接口的大小可变数组的实现。实现了所有可选列表操作,并允许包括 null 在内的所有元素。
  (2)size、isEmpty、get、set、iterator 和 listIterator 操作都以O(1)时间 运行,对于ArrayList的增删,大部分情况需要移动数组的元素,最坏的时间复杂度是O(n)。也就是说,ArrayList是查询较为快速,但增删相对较为耗时的数据结构。
  (3)ArrayList**不是同步**的。如果多个线程同时访问一个 ArrayList 实例,而其中至少一个线程从结构上修改了列表,那么它必须 保持外部同步。(结构上的修改是指任何添加或删除一个或多个元素的操作,或者显式调整底层数组的大小;仅仅设置元素的值不是结构上的修改。)
  (4)ArrayList继承AbstractList,而在AbstractList中有一个modCount成员变量,每次对ArrayList进行修改时modCount都要加1,个人认为这也是检测ArrayList是否改动的标志。
  在获取ArrayList的迭代器的时候,我们会使用iterator()方法,返回的迭代器就与modCount有莫大的关系,如果返回的迭代器中的expectedModCount与ArrayList中的modCount不一致,则认为ArrayList已经被修改,如果继续使用此迭代器的话,会抛出ConcurrentModificationException异常,这也是为什么有些时候操作了ArrayList后需要重新获取它 的迭代器的真正原因。
  (5)在每次add元素的时候,都会ensureCapacityInternal(size + 1);检测容量是否足够,如果不够,容量则按1.5倍增长。因此在添加大量元素前,应用程序可以使用 ensureCapacity 操作来增加 ArrayList 实例的容量。这可以减少递增式再分配的数量。
  (6)ArrayList的内部实现其实用的是数组,private transient Object[] elementData;,细心的盆友可以看出它的关键字是transient,看到这个关键字,都以为此数组是不可序列化的,其实不然,因为ArrayList实现了Serializable的writeObject()可以客制化,ArrayList实现writeObject并且强制将transient elementData序列化。那么为什么这样设计呢?个人认为是因为ArrayList内部实现是数组,大部分情况下会有空值,比如elementData的大小是10,但实际只有6个元素,那么剩下的4个元素没有实际的意义,如果直接将此标识为可序列化,那么最终会把空值同样序列化,因此将elementData设计为transient,然后实现Serializable的writeObject()方法将其序列化,只序列化实际存储的元素,而不是整个数组。
  

源码

//继承AbstractList,支持泛型
    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;  

        //元素数目  
        private int size;  

        //初始化一个initialCapacity大小的ArrayList  
        public ArrayList(int initialCapacity) {  
            super();//父类的构造函数本身没做什么事情  
            if (initialCapacity < 0)//检查是否合法  
                throw new IllegalArgumentException("Illegal Capacity: "+  
                                                   initialCapacity);  
            this.elementData = new Object[initialCapacity];
        }  

        //初始化一个空的ArrayList  
        public ArrayList() {  
            super();  
            this.elementData = EMPTY_ELEMENTDATA;//数组为空  
        }  

        //按c里面的元素来初始化一个ArrayList  
        public ArrayList(Collection<? extends E> c) {
        //c中的元素转换为数组,elementData的类型为Object[],此处不需要类型转换    
            elementData = c.toArray();
            size = elementData.length;  
            if (elementData.getClass() != Object[].class)//确保elementData数组是object类型
                elementData = Arrays.copyOf(elementData, size, Object[].class);  
        }  

      //相当于压缩ArrayList,比如ArrayList有10个空间,现在只存储了5个元素,
      //通过该方法将ArrayList的空间变为5个  
        public void trimToSize() {  
            modCount++;//修改次数+1  
            if (size < elementData.length) {  
                elementData = Arrays.copyOf(elementData, size);  
            }  
        }  

        //申请minCapacity个空间  
        public void ensureCapacity(int minCapacity) {  
            //获取表默认的初始容量,空表为0,其他的默认为DEFAULT_CAPACITY 
            int minExpand = (elementData != EMPTY_ELEMENTDATA)? 0: DEFAULT_CAPACITY; 
            //只有minCapacity大于默认初始容量,才申请新的大小的空间  
            if (minCapacity > minExpand) {
                ensureExplicitCapacity(minCapacity);//执行扩容  
            }  
        }  
        //申请minCapacity个空间  
        private void ensureCapacityInternal(int minCapacity) {  
            if (elementData == EMPTY_ELEMENTDATA) { 
                //minCapacity取DEFAULT_CAPACITY和minCapacity的最大值  
                minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
            }  

            ensureExplicitCapacity(minCapacity);//执行扩容  
        }  
        //执行扩容,容量为minCapacity  
        private void ensureExplicitCapacity(int minCapacity) {  
            modCount++;//修改次数+1  

            //只有minCapacity大于默认初始容量,才执行扩容  
            if (minCapacity - elementData.length > 0)  
                grow(minCapacity);//执行扩容,容量为minCapacity  
        }  

        //JVM支持大小为MAX_ARRAY_SIZE容量的数组  
        private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;  

        //执行扩容  
        private void grow(int minCapacity) {  
            //记录老的容量值  
            int oldCapacity = elementData.length;  
            //新的容量按老容量的1.5倍来扩容  
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            if (newCapacity - minCapacity < 0)  
                //如果申请的容量比目前容量的1.5倍还要大  
                newCapacity = minCapacity;
            if (newCapacity - MAX_ARRAY_SIZE > 0)
                newCapacity = hugeCapacity(minCapacity);  
            //增加新的空间,新增加空间的长度为newCapacity,原有的元素放到新空间的前面  
            elementData = Arrays.copyOf(elementData, newCapacity);
        }  

        private static int hugeCapacity(int minCapacity) {  
            if (minCapacity < 0) //溢出了  
                throw new OutOfMemoryError();  
            return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE :MAX_ARRAY_SIZE;  
        }  

        //返回元素数目  
        public int size() {  
            return size;  
        }  

        //判断ArrayList是否为空
        public boolean isEmpty() {  
            return size == 0;  
        }  

        //判断是否包含值为o的元数  
        public boolean contains(Object o) {  
            return indexOf(o) >= 0;
        }  

        //定位第一个值为o的元素  
        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;  
        }  

        //定位最后一个值为o的元素  
        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;  
        }  

        //执行浅拷贝  
        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) {  
                throw new InternalError();  
            }  
        }  

        //转换为数组  
        public Object[] toArray() {  
            return Arrays.copyOf(elementData, size);  
        }  

        //转换为a类型的数组  
        @SuppressWarnings("unchecked")  
        public <T> T[] toArray(T[] a) {  
            if (a.length < size)  
                // 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[size] = null;  
            return a;  
        }  

        //定位第index个元素  
        @SuppressWarnings("unchecked")  
        E elementData(int index) {  
            return (E) elementData[index];//O(1)操作  
        }  

        //获取第index个元素  
        public E get(int index) {  
            rangeCheck(index);  

            return elementData(index);  
        }  

        //设置第index个元素的值为element  
        public E set(int index, E element) {  
            rangeCheck(index);  

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

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

        //第index个位置添加元素element  
        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;  
        }  

        //删除值为o的第一个元素  
        public boolean remove(Object o) {  
            if (o == null) {  
                for (int index = 0; index < size; index++)  
                    if (elementData[index] == null) {  
                        fastRemove(index);  
                        return true;  
                    }  
            } else {  
                for (int index = 0; index < size; index++)  
                    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  
        }  

        //将ArrayList置空  
        public void clear() {  
            modCount++;  

            //保证GC可以工作
            for (int i = 0; i < size; i++)  
                elementData[i] = null;  

            size = 0;  
        }  

        //将c里面的所有元素都添加到当前表的尾部  
        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;  
        }  

        //将c里面的所有元素都添加到第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;  
        }  

        //删除formIndex和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;  
        }  

        //index范围检查  
        private void rangeCheck(int index) {  
            if (index >= size)  
                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));  
        }  

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

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

        //删除所有c里面不包含的元素  
        public boolean removeAll(Collection<?> c) {  
            return batchRemove(c, false);  
        }  

        //删除所有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);  

            // 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 {  
            elementData = EMPTY_ELEMENTDATA;  

            // Read in size, and any hidden stuff  
            s.defaultReadObject();  

            // Read in capacity  
            s.readInt(); // ignored  

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

        //返回一个从index开始的双向迭代器  
        public ListIterator<E> listIterator(int index) {  
            if (index < 0 || index > size)  
                throw new IndexOutOfBoundsException("Index: "+index);  
            return new ListItr(index);  
        }  

        //返回一个双向迭代器  
        public ListIterator<E> listIterator() {  
            return new ListItr(0);  
        }  

        //返回迭代器  
        public Iterator<E> iterator() {  
            return new Itr();  
        }  

        //私有内部类,从第0个元素开始的单向迭代器  
        private class Itr implements Iterator<E> {  
            int cursor;       // index of next element to return  
            int lastRet = -1; // index of last element returned; -1 if no such  
            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];  
            }  

            public void remove() {  
                if (lastRet < 0)  
                    throw new IllegalStateException();  
                checkForComodification();  

                try {  
                    ArrayList.this.remove(lastRet);  
                    cursor = lastRet;  
                    lastRet = -1;  
                    expectedModCount = modCount;  
                } catch (IndexOutOfBoundsException ex) {  
                    throw new ConcurrentModificationException();  
                }  
            }  

            final void checkForComodification() {  
                if (modCount != expectedModCount)  
                    throw new ConcurrentModificationException();  
            }  
        }  

        //私有内部类,从第index元素开始的双向迭代器  
        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;  
            }  

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

            @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 set(E e) {  
                if (lastRet < 0)  
                    throw new IllegalStateException();  
                checkForComodification();  

                try {  
                    ArrayList.this.set(lastRet, e);  
                } catch (IndexOutOfBoundsException ex) {  
                    throw new ConcurrentModificationException();  
                }  
            }  

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

    }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值