android ArrayList

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方法并不会改变已有数据的长度

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 以上是ArrayList的类前注释。大致意思如下:ArrayList是底层用数组实现的List。支持增删改等操作。...
    Reiya阅读 608评论 0 2
  • 从最基础的数据结构 数组|链表|树 开始,基于这些基础数据结构通过各种设计组合成具备特定功能的数据结构,这些结构是...
    轩居晨风阅读 1,232评论 2 31
  • 一、前言 上面这幅图是 集合框架涉及到的类的继承关系,从集合类的角度来看,它分为两个大类: 和 。 1.1 Col...
    泽毛阅读 4,802评论 5 19
  • 一、基本数据类型 注释 单行注释:// 区域注释:/* */ 文档注释:/** */ 数值 对于byte类型而言...
    龙猫小爷阅读 4,291评论 0 16
  • “在众多的迟到者之中,我有一个名字。——费尔南多.佩索阿” 循童年的味觉记忆, 在集市上寻找一盏姹紫的吃食。 这条...
    柳阔阅读 212评论 2 9