Arraylist:
基本知识点:
1.arrayList 内部构造是一个数组,所以构造时存在着一定的容量(负载因子),所以当数组列表满了的时候会出现自动扩容的状态。
2.第二个知识点很简单,该类不是一个线程安全类,所以当你在使用迭代器进行的迭代的时候你不能修改其中的数据,不然会有一个ConcurrentModificationException。这样的运行失败问题也称为快速失败。
源码分析:
1、跟踪ArryayList() 构造函数之后有惊喜:
如果调用该构造函数,arrayList内部构造会默认将指针指向一个空的数组(EMPTY_ELEMENTDATA),并且在第一调用add()方法之后才会根据默认容量大小(DEFAULT_CAPACITY)大小进行扩容,以后的每次扩容都是n+n的平方
(int newCapacity = oldCapacity + (oldCapacity >> 1))
而扩容的时候就需要把旧的数组里面的东西copy到新的数组里面去,会导致内容消耗。所以,如果你使用ArrayList的空构造函数的时候,那么就默认了你务必会进行一次扩容。然后我就自己在想,为什么要设计这样,为什么不一new一个ArrayList就直接构造一个大小(elementData)为10的数组呢?
我自己的猜想是这样的,java工程师应该是想模拟数组的结构,因为有时候或许new 一个ArrayList 就是需要让它为空的,或者对于从一个空数组复制数据到一个新的数组
Arrays.copyOf(elementData, newCapacity)
消耗的性能不值一提吧。所以查杀完源码之后,以后对于自己编写的程序一定要注意,如果明确知道或者大概知道数据量的大小的话,要提前输入ArrayList的容量,减少少ArrayList扩容对性能的影响。
2.里面存在size记录当前真实的存储容量。
发现trimToSize()方法,可以把当前未存储的数组空间的切除,即通过数组复制的方式来调整ArrayList缓存数组的大小
public void trimToSize() {
modCount++;
if (size < elementData.length) {
elementData = Arrays.copyOf(elementData, size);
}
}