zoukankan      html  css  js  c++  java
  • ArrayList源码解析

    java.lang.Object 
        java.util.AbstractCollection<E> 
            java.util.AbstractList<E> 
                java.util.ArrayList<E> 

    实现接口

    Serializable, Cloneable, Iterable<E>, Collection<E>, List<E>, RandomAccess 

    基本属性

    transient Object[] elementData;  //存放数组的元素,transient表示该字段不进行序列化操作
    private int size;    //已经放入数组中的元素个数,非数组的长度

    源码解析

    public class ArrayList<E> extends AbstractList<E>
            implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
        //可序列化版本号
        private static final long serialVersionUID = 8683452581122892189L;
    
        //默认的初始化数组大小 为10 .
        private static final int DEFAULT_CAPACITY = 10;
    
        //实例化一个空数组
        private static final Object[] EMPTY_ELEMENTDATA = {};
    
        //存放List元素的数组
        private transient Object[] elementData;
    
        //List中元素的数量,和存放List元素的数组长度可能相等,也可能不相等
        private int size;
    
        //构造方法,指定初始化的数组长度
        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数组
            elementData = c.toArray();
            size = elementData.length;
            //如果c.toArray返回的不是Object[]类型的数组,转换成Object[]类型
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        }
    
        //改变数组的长度,使长度和List的size相等。
        public void trimToSize() {
            modCount++;
            if (size < elementData.length) {
                elementData = Arrays.copyOf(elementData, size);
            }
        }
    
        //确定ArrayList的容量
        //判断当前elementData是否是EMPTY_ELEMENTDATA,若是设置长度为10
        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);
            }
        }
        //当前位置和默认大小之间取最大值
        private void ensureCapacityInternal(int minCapacity) {
            if (elementData == EMPTY_ELEMENTDATA) {
                minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
            }
    
            ensureExplicitCapacity(minCapacity);
        }
    
        private void ensureExplicitCapacity(int minCapacity) {
            modCount++;
    
            // overflow-conscious code
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);
        }
    
        //数组的最大容量
        private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    
        //扩容操作
        private void grow(int minCapacity) {
            // overflow-conscious code
            int oldCapacity = elementData.length;
            //容量扩充1.5倍
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            if (newCapacity - minCapacity < 0)
                newCapacity = minCapacity;
            if (newCapacity - MAX_ARRAY_SIZE > 0)
                newCapacity = hugeCapacity(minCapacity);
            // minCapacity is usually close to size, so this is a win:
            //生成一个长度为newCapacity数组,并将elementData数组中元素拷贝到新数组中,并将新数组的引用赋值给elementData
            elementData = Arrays.copyOf(elementData, newCapacity);
        }
    
        private static int hugeCapacity(int minCapacity) {
            if (minCapacity < 0) // overflow
                throw new OutOfMemoryError();
            return (minCapacity > MAX_ARRAY_SIZE) ?
                Integer.MAX_VALUE :
                MAX_ARRAY_SIZE;
        }
    
        //返回数组中已经放入的元素个数,非数组长度
        public int size() {
            return size;
        }
    
        //List是否为空
        public boolean isEmpty() {
            return size == 0;
        }
    
        //判断是否包包含指定元素
        public boolean contains(Object o) {
            return indexOf(o) >= 0;
        }
    
        //查找指定的元素,存在返回下标,不存在放回 -1 
        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;
        }
    
        //倒序查找元素,存在放回下标,不存在返回-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;
        }
    
        //因为实现了clone接口,所以需要重写clone()方法,实现对象的拷贝
        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();
            }
        }
    
        //将集合转化为数组
        public Object[] toArray() {
            return Arrays.copyOf(elementData, size);
        }
    
        //转化为指定类型的数组元素,推荐使用此方法
        @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;
        }
    
        // Positional Access Operations
        //放回指定位置的数组元素
        @SuppressWarnings("unchecked")
        E elementData(int index) {
            return (E) elementData[index];
        }
    
        //返回列表中指定位置的元素
        public E get(int index) {
            rangeCheck(index);
    
            return elementData(index);
        }
    
        //设置指定位置的元素,并返回被替换的元素
        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;
        }
        //将元素添加到指定位置上,从指定位置的元素开始所有元素向后移动,为新添加的元素提供位置
        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++;
        }
    
        //删除指定位置的元素,其他元素做相依的移动,并将最后一个元素置空,方便垃圾处理机制回收,防止内存泄露,并返回删除的元素值
        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;
        }
    
        //删除元素方法
        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;
        }
    
        //快速删除执行操作
        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
        }
    
        //清除列表
        public void clear() {
            modCount++;
    
            // clear to let GC do its work
            for (int i = 0; i < size; i++)
                elementData[i] = null;
    
            size = 0;
        }
    
        //添加方法,添加的元素为集合
        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;
        }
    
        //从指定位置开始添加集合元素
        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;
        }
    
        //范围删除方法
        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;
        }
    
        //下标检测方法,如果不合法,抛出IndexOutOfBoundsException异常
        private void rangeCheck(int index) {
            if (index >= size)
                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
        }
    
        /**
         * A version of rangeCheck used by add and addAll.
         */
        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;
        }
    
        //删除所有元素
        public boolean removeAll(Collection<?> c) {
            return batchRemove(c, false);
        }
    
        
        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();
                }
            }
        }
    
        //迭代方法,返回内部类实例
        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();
        }
    
        //内部类,实现Iterator接口
        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;
            //是否还有下一个元素,返回true or false 
            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;   //获取外部类的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();
            }
        }
    
        //省略了ListItr、SubList两个内部类
    }
  • 相关阅读:
    【crontab】误删crontab及其恢复
    New Concept English there (7)
    New Concept English there (6)
    New Concept English there (5)
    New Concept English there (4)
    New Concept English there (3)
    New Concept English there (2)Typing speed exercise
    New Concept English there (1)Typing speed exercise
    New Concept English Two 34 game over
    New Concept English Two 33 94
  • 原文地址:https://www.cnblogs.com/fangdie/p/12611951.html
Copyright © 2011-2022 走看看