2019.7.16 ArrayList和LinkedList的区别

1. 底层不同

  • ArrayList基于动态数组
  • LinkedList基于双向链表

2. 查询、插入、删除的效率不同

  • 对于随机访问get,设定值set方法,ArrayList的效率高于LinkedList,因为动态数组可以随机访问的,适用于查询很多的场景。而LinkedList需要通过移动指针一步一步到节点处,比较费时。
  • 对于插入、删除方法,LinkedList的效率要优于ArrayList,为啥呢,LinkedList只需要移动指针指向需要的节点对象即可以,而ArrayList需要移动数据来填补被删除的对象的空间

3. 使用场景不同

  • 当经常需要执行查询操作时,适合使用ArrayListList

  • 当我们不知道数据量的大小时或者经常执行插入删除的操作,适合使用LinkedList

4. ArrayList需要扩容的问题
当ArrayList的空间不够用时,会自动申请内存,叫做扩容。

/**
 * minCapacity:当前需要的容量是minCapacity,扩容后的容量应当大于等于minCapacity
 */
private void grow(int minCapacity) {

    int oldCapacity = elementData.length; // 扩容前的容量
    int newCapacity = oldCapacity + (oldCapacity >> 1); // 新容量等于扩容前容量的1.5倍
    // 如果新容量还不够用,那么就扩容到minCapacity得了
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity; 

    // 如果新容量超过ArrayList最大容量,那么就用最大容量了(ArrayList的容量总得有个上限吧)
    // 插一句:最大容量为:0x7fffffff-8
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);

    // 扩容的核心就是这句话,将旧数组里的内容复制到新数组里
    // 这个操作很耗时,因此我们应当尽量减少扩容
    elementData = Arrays.copyOf(elementData, newCapacity);
}

在这里可以很清楚的看到扩容容量的计算:
int newCapacity = oldCapacity + (oldCapacity >> 1)
调用无参构造函数默认初始容量为10
其中oldCapacity是原来的容量大小,oldCapacity >> 1 为位运算的右移操作,右移一位相当于除以2,所以这句代码就等于int newCapacity = oldCapacity + oldCapacity / 2;即容量扩大为原来的1.5倍(注意我这里使用的是jdk1.8,没记错的话1.7也是一样的),获取newCapacity后再对newCapacity的大小进行判断,如果仍然小于minCapacity,则直接让newCapacity 等于minCapacity,而不再计算1.5倍的扩容。然后还要再进行一步判断,即判断当前新容量是否超过最大的容量 if (newCapacity - MAX_ARRAY_SIZE > 0),如果超过,则调用hugeCapacity方法,传进去的是minCapacity,即新增元素后需要的最小容量:
在这里插入图片描述

转载:https://blog.csdn.net/u010429424/article/details/76220058

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章