java集合之ArrayList
ArrayList的实现是一个动态数组,从源码中也可以看出。这就决定了他的查找效率高,可以直接通过下标访问。但是对于删除和增加元素,需要大量的移动元素,所以插入和删除的效率就很低。
ArrayList不是线程安全的,只能用在单线程环境下,多线程环境下可以考虑用Collections.synchronizedList(List l)函数返回一个线程安全的ArrayList类。
构造方法:
ArrayList(int initialCapacity) 构造具有指定初始容量的空列表
ArrayList() 默认容量是10
ArrayList(Collection<? extends E> c) 构造包含指定集合的元素的列表,按集合的迭代器返回元素的顺序排列
重点看看添加方法是如何扩容的
跟随方法的调用发现了扩容的时机:
如果添加元素以后的容量大于当前数组的长度了,则会执行扩容方法
扩容方法:
int newCapacity = oldCapacity + (oldCapacity >> 1);
已经很明确的告诉我们数组扩容后的容量是原数组的1.5倍。右移一位就相当于除以2,再加上原来数组的长度。即为原来的1.5倍
接着Arrays.copyOf(elementData, newCapacity);方法追踪下去会发现,底层调用的是System类的arraycopy(Object src, int srcPos, Object dest, int destPos, int length)方法。这也说明了ArrayList的扩容是浅拷贝。
浅拷贝和深拷贝
浅拷贝说白了就是把数组的引用拷贝一份。拷贝的数组元素,和被拷贝的数组元素还是指向同一个对象。
深拷贝和浅拷贝的区别是深拷贝连同数据一块复制了一份,两个数组之间没有关系
移除方法
第一步是先检查范围。
源码中可以看出System.arraycopy(elementData, index+1, elementData, index, numMoved);就是在移动元素,然后将最后一个元素空出来置为null。