ArrayList源码学习

arraylist


1、总体关系图

 

 

1.1:Serializable接口

这是一个空接口,只有实现了这个接口的对象才可以进行序列化。

然后这个序列化id是为了保证反序列化成功也就是在运行时来判断id是否一致来缺点统一版本。

 

 

transient关键字修饰的属性不会被序列化。那arraylist的元素怎么进行序列化和反序列化?

 

 

其实它重写了writeObject方法,是为了节省空间。因为arraylist会进行自动扩容,所以存放的数组永远会有空位,但是序列化没必要将空的也进行序列化。所以它将数组中不是空的位置进行了序列化。

1.2 Cloneable 接口

这也是一个空接口用来做标记用的,在进行克隆的时候会去判断有没有实现这个接口,如果没有实现 Cloneable的类对象调用clone()就会抛出CloneNotSupportedException

1.3 RandomAccess 接口

也是一个空接口,做标记用的。用以标记实现的List集合具备快速随机访问的能力。快速随机访问就是可以随机访问List中的任何一个元素。

当一个List拥有快速访问功能时,其遍历方法采用for循环最快速。而没有快速访问功能的List,遍历的时候采用Iterator迭代器最快速。(这样我们就能在遍历之前先去判断一下,然后在决定使用什么遍历方式)

2、方法源码

2.1 构造方法

2.2 trimToSize()

目的:将动态数组中的容量调整为数组中实际容量,也是调用的Arrays的拷贝方法。

2.3 ensureCapacity()

目的:设定指定容量。为什么要有一个这个方法,为了外部调用的时候不需要关心内部modcount的改变,直接封装在这里面对modcount进行改变。我感觉也有分离职责的原因。

最后调用的是grow方法进行扩容。这里面的最大容量是Integer.MAX_VALUE - 8为了防止oom。

2.4 isEmpty()

目的:判断是否为空

2.5 contains()

目的:是否包含这个元素。

这里分出来是为了防止参数为空然后调用了equal()方法导致空指针异常

 

 

如果想返回最后一个出现的下标,那就倒着遍历数组就行了。

2.6 clone()方法

2.7 get()、set()方法

2.8 add()方法

2.9 remove()方法

2.10 clear()方法

2.11 addAll()方法

 

 

2.12 removeAll()方法

2.13 foreach()方法

eg:

2.14 replaceAll()方法

eg:输出2、3、4、5

2.15 sort()方法

 

 

posted @ 2022-10-09 14:41  大大怪下士  阅读(8)  评论(0编辑  收藏  举报