源码分析之ArrayList
1. 基于数组实现,可随机访问。实现了RandomAccess接口。数组默认大小为10。
2. 添加元素
使用ensureCapacityInternal()方法保证容量充足。容量不够时,用grow()方法来进行扩容,新容量为原来1.5倍。扩容操作会调用Arrays.copyof(),将元素组复制到新数组中。代价很高,因为创建时最好确定大概容量大小,减少扩容次数。
3.删除元素
适应System.arraycopy()将index+1后面的元素都复制到index位置。复杂度为O(N),所以删除元素代价很高。
4.序列化
因为Arraylist基于数组实现,具有动态扩容的特性。因此保存的元素不一定都会使用。所以没必要全部序列化。
保存元素的数组elementdata.使用transient修饰。该关键字声明数组默认不会被序列化。
Arraylist实现了readObject()和writeObject()来控制只序列化数组中有元素填充的部分。
5. fail-fast
modCount用来记录Arraylist发生结构变化的次数。数组中删除或添加至少一个元素的操作。仅仅改变元素的值不算结构变化。
进行序列化或者迭代操作时会进行对比操作前后的modCount,如果改变了,需要抛出ConcurrentModificationException.。
2. 添加元素
使用ensureCapacityInternal()方法保证容量充足。容量不够时,用grow()方法来进行扩容,新容量为原来1.5倍。扩容操作会调用Arrays.copyof(),将元素组复制到新数组中。代价很高,因为创建时最好确定大概容量大小,减少扩容次数。
3.删除元素
适应System.arraycopy()将index+1后面的元素都复制到index位置。复杂度为O(N),所以删除元素代价很高。
4.序列化
因为Arraylist基于数组实现,具有动态扩容的特性。因此保存的元素不一定都会使用。所以没必要全部序列化。
保存元素的数组elementdata.使用transient修饰。该关键字声明数组默认不会被序列化。
Arraylist实现了readObject()和writeObject()来控制只序列化数组中有元素填充的部分。
5. fail-fast
modCount用来记录Arraylist发生结构变化的次数。数组中删除或添加至少一个元素的操作。仅仅改变元素的值不算结构变化。
进行序列化或者迭代操作时会进行对比操作前后的modCount,如果改变了,需要抛出ConcurrentModificationException.。