JDK版本11
ArrayList类声明
其中RandomAccess、Cloneable、Serializable都是标记接口,用来表示ArrayList支持随机读取、克隆和序列化反序列化。
ArrayList集合添加元素底层原理
- 利用空参创建集合,在底层创建一个默认长度为0的数组。
- 添加第一个元素时,底层会创建一个新的长度为10的数组(elementData)。
- 存满时,会扩容1.5倍,然后将元素拷贝到新数组中。
- 如果一次添加多个元素,1.5倍还放不下,则新创建数组的长度以实际为准。
空参初始化
ArrayList无参构造会创建一个默认长度为0的数组。
transient修饰的底层数组
transient Object[] elementData;
transient修饰的变量不会参与序列化和反序列化的过程。
写到这里有一个疑问,既然底层的数组不会被序列化那么对象传输、或者持久化时候数据是怎么保存的?
我注意到了两个方法,真相大白了。原来是ArrayList自己实现了底层数组的
序列化
和反序列化,
这两个自己实现的序列化并不是没有序列化,而是仅仅对有效的数据进行了序列化。
这样有什么好处呢?
我们知道ArrayList的底层数组是会扩容的,但是不会缩容,并且ArrayList可以删除元素。
想象下面场景,我有一个ArrayList对象存储了100万条数据,但是因为后续操作,我删除的只剩下了一条数据,如果底层数组不被transient修饰,那么这999999条空数据都会被序列化进行数据持久化或者网络传输,这样是十分浪费资源的,但是ArrayList自己实现的序列化只用序列化一条有效的数据进行传输,这样效率就会十分高。