关于ArrayList的小知识

关于ArrayList的小知识

1. LinkedList与ArrayList的区别

  1. 首先两者的内部结构不同:ArrayList是基于在动态数组的顺序表数据结构。顺序表的存储地址是连续的。而LinkedList 是一个继承于AbstractSequentialList的双向链表,它是在链表的基础上实现的。它也可以被当作堆栈、队列或双端队列进行操作。链表的存储地址是不连续的,每一个存储地址都通过指针指向。

  2. 对于随机访问get和set操作,ArrayList比LinkedList的性能要高,因为LinkedList要移动指针。

  3. 对于新增和删除操作则相反,LinedList比ArrayList性能要高,因为ArrayList要移动数据,需要重新排放,而LinkedList只需要把指针重新指向就可以了

2. ArrayList的底层实现与扩容

ArrayList的底层实现:

ArrayList是List接口的可变数组的实现:

// An highlighted block
transient Object[] elementData;
private int size;

List<String> list = new ArrayList<String>(100);
list.add(“aaa”);
list.add(“bbb”);
list.add(“ccc”);
list.add(“ddd”);

list.remove(1);

移除操作,就是将指定索引位置以后的元素都向前挪了一位,(这里调用了System.arraycopy方法,该方法的优势在于它使用的是内存复制,省去了大量的数组寻址访问等时间),然后执行elementData[–size] = null;将size减1,并将最后一个元素置为空

// An highlighted block
    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;
}
ArrayList的扩容

每次向数组中添加元素时,都要去检查元素的个数会不会超出当前数组的长度,如若长度超出,数组就会进行扩容,以满足添加数据的需求。数组扩容通过一个公开的方法ensureCapacity(int minCapacity)来实现, 而该方法最终又会调用一个私有的grow方法进行扩容。我们每扩容一次其容量约为原来的1.5倍,具体代码是将数组原来长度跟数组原来长度右移一位的值求和。以至于为什么用位操作,是因为对于计算机而言位操作的效率更高。

    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        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:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

注意:
数组进行扩容时,会将老数组中的元素重新拷贝一份到新的数组中,这种操作的代价是很高的,因此在使用时,我们应该最大限度避免数组容量的扩张的次数。所以在初始化ArrayList的时候最好估算一下大概需要多少容量,也可以使用 ensureCapacity来手动添加ArrayList实例的容量,尽量减少频繁调整容量的开销和效率

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值