ArrayList的实现原理(一)

一、ArrayList的实现原理?

1、ArrayList概述?

ArrayList 是 List 接口的可变数组的实现。实现了所有可选列表操作,并允许包括 null 在内的所有元素。除了实现List接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。每个ArrayList实例都有一个容量,该容量是指用来存储列表元素的数组的大小。它总是至少等于列表的大小。随着向ArrayList中不断添加元素,其容量也自动增长。自动增长会带来数据向新数组的重新拷贝,因此,如果可预知数据量的多少,可在构造ArrayList时指定其容量。在添加大量元素前,应用程序也可以使用ensureCapacity操作来增加ArrayList实例的容量,这可以减少递增式再分配的数量。

注意,此实现不是同步的。如果多个线程同时访问一个ArrayList实例,而其中至少一个线程从结构上修改了列表,那么它必须保持外部同步。

2. ArrayList 的实现

对于ArrayList而言,它实现List接口、底层使用数组保存所有元素。其操作基本上是对数组的操作。下面我们来分析ArrayList的源代码:

1) 底层使用数组实现

Java 代码

2)构造方法:

ArrayList 提供了三种方式的构造器,可以构造一个默认初始容量为 10 的空列表、构造一个指定初始容量的空列表以及构造一个包含指定collection的元素的列表,这些元素按照该collection的迭代器返回它们的顺序排列的。

Java 代码

a:构造一个默认初始容量为 10 的空列表的构造器:

ArrayList的默认长度


构造器(初始容量)


b:构造一个指定初始容量的空列表的构造器

构造器


c:构造一个包含指定collection的元素的列表的构造器

构造器


注:详细可见ArrayList的源码。

合并后的三个构造器


3)存储

ArrayList 提供了set(int index, E element)、add(E e)、add(int index, E element)、addAll(Collection c)、addAll(int index, Collection c)这些添加元素的方法。

下面我们一一讲解:

Java 代码

set(int index, E element)


add(E e)


add(int index, E element)


addAll(Collection c)


addAll(int index, Collection c)  


以上均是ArrayList的源码,有兴趣的可以看一下,有助于理解。

4)读取

java 代码

get(int  index)根据索引读取


5)删除

ArrayList 提供了根据下标或者指定对象两种方式的删除功能。如下:

java 代码

第一种:

remove(int   index):根据索引remove


第二种:

remove(Object o):直接remove对象(arraylist中允许有null,所以要分两种情况)


注意:从数组中移除元素的操作,也会导致被移除的元素以后的所有元素的向左移动一个位置。

6)调整数组容量:

从上面介绍的向ArrayList中存储元素的代码中,我们看到,每当向数组中添加元素时,都要去检查添加后元素的个数是否会超出当前数组的长度,如果超出,数组将会进行扩容,以满足添加数据的需求。数组扩容通过一个公开的方法ensureCapacity(int minCapacity)来实现。在实际添加大量元素前,我也可以使用ensureCapacity来手动增加ArrayList实例的容量,以减少递增式再分配的数量。

源码


整合


从上述代码中可以看出,数组进行扩充时,会将数组中的元素重新拷贝一份到新的数组中,每次数组容量的增长大约是其容量的1.5倍。这种操作的代价是很高的,因此在实际使用中,我们应该尽量避免数组容量的扩张。当我们可预知要保存的元素的多少是,要在构造ArrayList实例时,就指定其容量,以避免扩容的发生。或者根据实际需求,通过调用ensureCapacity方法来手动增加ArrayList实例的容量。

ArrayList还给我们提供了将底层数组的容量调整为当前列表保存的实际元素的大小的功能。它可以通过trimToSize方法来实现。代码如下:

trimToSize

7)Fail-Fast机制

        ArrayList也采用了快速失败的机制,通过记录modCount参数来实现。在面对并发的修改时,迭代器很快就会完全失败,而不是冒着将来某个不确定时间发生任意不确定行为的风险。

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

推荐阅读更多精彩内容

  • 概述 ArrayList是List接口的可变数组的实现。实现了所有可选列表操作,并允许包括 null 在内的所有元...
    曹振华阅读 247评论 0 0
  • 这只猫是本人亲自画的, 没有模仿全凭感觉 拿起笔上手就画 虽然还有很多不足 我会继续努力钻研 如有不满还请多多指教
    囧姐阅读 260评论 0 1
  • 不了解 DSOframer 的朋友,可以先参考文章 DSOframer 的简单介绍和资源整理。 在使用 DSOfr...
    劼哥stone阅读 1,539评论 0 0
  • 一、环境需求 1、安装Homebrew Homebrew是OS X的套件(包)管理器,用于安装Node.js和一些...
    LinXunFeng阅读 271评论 0 0
  • 刚才看见一个阿姨(目测应该是小孩的奶奶或外婆,后来听到小男孩叫她奶奶)带着俩小孩在花埔边上晒太阳,一个是女孩几个月...
    阿耐普洱茶阅读 148评论 0 0