美文网首页
android ArrayList

android ArrayList

作者: 逍遥天_lpc | 来源:发表于2017-01-16 22:10 被阅读0次

    ArrayList是一基于动态数组实现的

     @Override 
    public boolean add(E object) {
         Object[] a = array;
         int s = size;
         if (s == a.length) {
            Object[] newArray = new Object[s +
                (s < (MIN_CAPACITY_INCREMENT / 2) ?
                MIN_CAPACITY_INCREMENT : s >> 1)];
         System.arraycopy(a, 0, newArray, 0, s);
         array = a = newArray;
         }
         a[s] = object;
         size = s + 1;
         modCount++;
         return true;
    }
    

    如果一直使用的是add方法增加数据,它的默认长度是12

     private static final int MIN_CAPACITY_INCREMENT = 12;
    

    当没次达到容量是,就会扩容,大概是增长50%,即

    s+s>>1
    

    所以容量的长度变化是0,12,18,27,40...以此类推(但具体值不一定是这样,因为还存在addAll方法,两者同时使用就不是这样了),扩容后会讲原先数据通过System.arraycopy复制一份给newArray,那么newArray就是扩容后并且有原先数据的新数组,随后再对变量array赋值,供下次使用

    但如果其中使用addAll方法时,原先数组的剩余容量小于新数据的长度的话,则会进行扩容,这次它的基数是原先数组已有的数据长度加上新数据的长度

    @Override public boolean addAll(Collection<? extends E> collection) {
         Object[] newPart = collection.toArray();
         int newPartSize = newPart.length;
         if (newPartSize == 0) {
             return false;
         }
         Object[] a = array;
         int s = size;
         int newSize = s + newPartSize; // If add overflows, arraycopy will fail
         if (newSize > a.length) {
             int newCapacity = newCapacity(newSize - 1);  // ~33% growth room
             Object[] newArray = new Object[newCapacity];
             System.arraycopy(a, 0, newArray, 0, s);
             array = a = newArray;
         }
         System.arraycopy(newPart, 0, a, s, newPartSize);
         size = newSize;
         modCount++;
         return true;
    }
    
     private static int newCapacity(int currentCapacity) {
         int increment = (currentCapacity < (MIN_CAPACITY_INCREMENT / 2) ?
                 MIN_CAPACITY_INCREMENT : currentCapacity >> 1);
         return currentCapacity + increment;
    }
    

    这边源码中虽然写的注释是33%左右的增加,但是我感觉还是50%左右,因为只是减了1,再去执行currentCapacity+currentCapacity >> 1,我也试过几个数字,这个increment值基本还是50%左右

    remove方法使用的原理是将index之后的数据拷贝了一份,并放在原先数组中,而这些数据存放的起始位置就是原先的index,拷贝完成后将最后一位(这里的最后一位并不是指整个数组的最后一位,而是排在末尾的数据,是有值的)置空

    @Override 
    public E remove(int index) {
         Object[] a = array;
         int s = size;
         if (index >= s) {
             throwIndexOutOfBoundsException(index, s);
         }
         @SuppressWarnings("unchecked") E result = (E) a[index];
         System.arraycopy(a, index + 1, a, index, --s - index);
         a[s] = null;  // Prevent memory leak
         size = s;
         modCount++;
         return result;
    }
    

    remove方法并不会改变已有数据的长度

    相关文章

      网友评论

          本文标题:android ArrayList

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