ArrayList的源码
变量 | 含义 | 默认值 |
---|---|---|
DEFAULT_CAPACITY | 默认的List初始化容量 | 10 |
EMPTY_ELEMENTDATA | 空实例的空数组内容 | {} |
DEFAULTCAPACITY_EMPTY_ELEMENTDATA | 共享的空数组实例,用于默认大小的空实例。 | {} |
elementData | 存储ArrayList内容的数组缓冲区,默认时 elementData == DEL | [] |
size | elementData数组大小 |
其中 elementData数组是ArrayList的存储结构,也就是说ArrayList使用数组存储元素, 但同时是使用transient进行修饰的,也就是不能序列化的,但实际上ArrayList实现了Serializable接口,那么这么做的原因时什么?
因为ArrayList具有自动扩容机制,元素到一定的大小就会自动扩容,这就会导致ArrayList中的元素一定不是满的,也就是说如果当前ArrayList的大小时50,实际元素可能远远小于50,此时就没有将全部elementData都序列化的必要了.
所以,ArrayList提供了一个writeObject方法,专门对elementData进行序列化.里面使用对小于size的所有元素进行序列化,就避免了上面阐述的问题.
1 | for (int i=0; i<size; i++) { |
构造函数源码
1 | /* 没有参数的情况下 */ |
常用方法源码
在看源码之前先通过下面这张图片了解以下如果新建一个ArrayList后添加一个元素的大致过程:
- add 添加方法
1 | /* 只有一个参数的添加 */ |
- remove 移除元素方法
1 | public E remove(int index) { |
- contain 是否包含
1 | public boolean contains(Object o) { |
- get 方法
1 | public E get(int index) { |
总结
- 有序性,可重复性 —> 因为内部使用数组实现,所以元素能够保证有序性且能够添加重复的元素
- 访问快 —> ArrayList实现了 RandomAccess 接口,能够通过get实现快速的随机访问.因为ArrayList其中内部存储是使用数组实现的,元素是连续的,通过下标就能够得到对应元素,所以检索会比较快.
- 插入删除慢 —> 插入和移除元素时,在扩容时,使用的是copyOf方法,也就是将原数组元素拷贝到目标数组的方式,效率低下.
- 非线程安全 —> ArrayList是非线程安全的,Vector是ArrayList的线程安全版本.在多线程时,可使用Vector代替ArrayList.
RandomAccess 只是一个标记接口,其中并没有实现方法,他的作用只是用来标记该结构支持随机访问.也就是说实现了这个接口的集合是支持 快速随机访问 策略的.举例来讲就是 ArrayList 的访问是随机访问,而 LinkedList的访问则是顺序访问的.
随机访问在使用fori循环时要比使用迭代器访问元素时效率高.