美文网首页
Android ArrayList 源码阅读

Android ArrayList 源码阅读

作者: AlanFu | 来源:发表于2018-05-28 11:39 被阅读0次

    参考文章

    前言

    Android的 ArrayList是我们开发中经常用到的集合工具类,一般可以理解为动态数组,顺序存储,读取快速。下文基于android-27 java.util.arraylist类进行解读,重点阅读一下android的构造方法,增删等方法。

    • 1 构造方法
    //传入初始化大小的构造方法
    public ArrayList(int initialCapacity) {
            //大于0直接new 出Object数组。
            if (initialCapacity > 0) {
                this.elementData = new Object[initialCapacity];
            } else if (initialCapacity == 0) {
    //等于0直接创建{};
                this.elementData = EMPTY_ELEMENTDATA;
            } else {
                //其它情况抛出异常
                throw new IllegalArgumentException("Illegal Capacity: "+
                                                   initialCapacity);
            }
        }
    //默认构造方法
    public ArrayList() {
           //创建默认数组
            this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
        }
    //传入集合构造方法
    public ArrayList(Collection<? extends E> c) {
            elementData = c.toArray();
            if ((size = elementData.length) != 0) {
                if (elementData.getClass() != Object[].class)
                    elementData = Arrays.copyOf(elementData, size, Object[].class);
            } else {
                // replace with empty array.
                this.elementData = EMPTY_ELEMENTDATA;
            }
        }
    
    • 2 成员变量与常量
    //默认数组大小
     private static final int DEFAULT_CAPACITY = 10;
    //空数组
     private static final Object[] EMPTY_ELEMENTDATA = {};
    //默认数组
     private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    //序列化透明的数组
     transient Object[] elementData; 
    //存放元素的个数
     private int size;
    
    
    • 3 add()方法
    //对外添加元素的方法
    public boolean add(E e) {
            //确保数组容量可以添加新元素。
            ensureCapacityInternal(size + 1);  // Increments modCount!!
          //放在数组最后。
            elementData[size++] = e;
            return true;
        }
    //计算数组容量,确保可以添加新元素。
    private void ensureCapacityInternal(int minCapacity) {
           //如果是默认数组
            if (elementData == DEFAULTCAPACITY_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 void grow(int minCapacity) {
            // overflow-conscious code
           //保存旧的大小
            int oldCapacity = elementData.length;
           //将旧的大小放大一倍赋值于新的
            int newCapacity = oldCapacity + (oldCapacity >> 1);
           //如果还不够,就直接将所需要的值赋值于新的
            if (newCapacity - minCapacity < 0)
                newCapacity = minCapacity;
           //如果新值大于了最大的数组大小(Integer.MAX_VALUE - 8;)
            if (newCapacity - MAX_ARRAY_SIZE > 0)
               //将Integer.MAX_VALUE赋值于newCapacity
                newCapacity = hugeCapacity(minCapacity);
              //对数组进行复制。
    //Arrays.copyOf实际调用了 java.lang.System 的public static native void //arraycopy(Object src,  int  srcPos,Object dest, int destPos,int length);
            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;
        }
    
    
    
    • 4 remove()方法
    //删除 下标
    public E remove(int index) {
    //如果大于元素个数,抛出异常
            if (index >= size)
                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    
            modCount++;
            E oldValue = (E) elementData[index];
    
            int numMoved = size - index - 1;
          //如果不是最后一个元素
            if (numMoved > 0)
               //数组进行移动与复制。
                System.arraycopy(elementData, index+1, elementData, index,
                                 numMoved);
           //将最后一个元素置为空
          //size减一。
            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
        }
    
    

    相关文章

      网友评论

          本文标题:Android ArrayList 源码阅读

          本文链接:https://www.haomeiwen.com/subject/kdiwjftx.html