美文网首页
ArrayList 需要了解的事情

ArrayList 需要了解的事情

作者: PageThinker | 来源:发表于2020-04-28 16:27 被阅读0次
    00.png

    ArrayList 是日常开发经常使用到的容器类。它能够方便的进行数据的查询、替换。但是因为其低层实现的原因在数据容量、性能、线程安全上都存在问题,主要涉及到下面的内容:

    (1)默认初始容量为 0,如果未指定容量则首次初始的容量为 10;同时其也是有容量限制的;

    (2)添加元素会涉及到数组扩容和数组元素拷贝,删除数组元素时同样也会涉及到数组的拷贝,这都会影响性能;

    (3)线程不安全,因为整个ArrayList 中没有涉及到线程安全的相关代码;

    下面是关键信息的分析。

    01,ArrayList 的主要的属性

    打开ArrayList 类之后,主要涉及到以下几个属性:

    01.png

    很显然 ArrayList 内部是通过数据来实现的,而数据就存储在 elementData 数组中,且允许存储的最大元素数是 MAX_ARRAY_SIZE。

    EMPTY_ELEMENTDATADEFAULTCAPACITY_EMPTY_ELEMENTDATA 主要用在实例化 ArrayList 时。

    当使用无参构造函数 new ArrayList() 时默认数组大小默认是大小为 0 的数组。

    02.png

    当使用有参构造函数 new ArrayList(initCapacity) 时,如果 initCapacity 小于等于 0 ,则默认数组大小为 0 的数组。

    03.png

    02,当执行 add() 方法时会发生什么?

    如下图所示,add 过程主要涉及到两步操作:ArrayList 中数组扩容;赋值;

    04.png 05.png

    数组扩容的过程如下:

    ​ (1)计算新的容量;

    ​ (2)将数组元素进行拷贝到扩容后的数组;

    如下面的代码所示:

    06.png

    上面扩容时有两步逻辑,

    如果存储数据的数组大小为 0,则新创建的数组大小时为 10;

    如果新容量没有超过最大容量,则使用新容量。新容量的计算 = 原来的容量 + 原来容量的一半,例如:

    150 = 100 + 100 >> 1

    03,当执行 remove() 时会进行数组拷贝

    在 ArrayList 中提供了 fastRemove() 方法,其实现如下:

    07.png

    可以看到 ArrayList 有多处会用到 System.arrayCopy() 方法。

    因此在使用ArrayList时,如果考虑到性能

    (1)初始化时指定初始化的容量大小,避免 add() 操作时的数据扩容和数组拷贝;

    (2)避免数组中数据的删除操作;

    ArrayList 中还提供了很多实用方法,如果感兴趣可以详细阅读其实现。

    实战TDD(1):体验

    相关文章

      网友评论

          本文标题:ArrayList 需要了解的事情

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