最近事比较多,转眼一看,已经一个多月没更新博客了,万丈高楼平地起,准备花一段时间对Java中基本的数据结构作个归纳整理。
ArrayList
这个数据结构相信对于接触Java的人来说,最熟悉不过了,它本身是一个基于数组实现
的集合。
ArrayList
默认初始化的容量大小为
private static final int DEFAULT_CAPACITY = 10;
扩容
我们通常使用ArrayList
过程中,似乎可以不停的往里面添加各种数据,那它到底是怎么实现的呢?这是笔者根据源码整理的大致的扩容过程:
每次添加新元素的时候,
ArrayList
内部都会将当前的容量+1
,得到目标容量minCapacity
大小,然后和当前的数组容量对比,如果目标容量大于当前容量
,就会调用grow方法
进行扩容操作,每次扩容,大小都会增加1.5倍
,然后会调用Arrays.copyOf
将旧数组中的元素复制到新数组中,最后移动新数组的下标,将新元素进行赋值。
下面是扩容方法的实现过程:
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
特性
ArrayList特性 | 描述 |
---|---|
是否允许空 | 允许 |
是否允许重复数据 | 允许 |
是否有序 | 有序 |
是否线程安全 | 非线程安全 |
因为ArrayList
不是线程安全的,因此多线程环境下可以考虑用Collections.synchronizedList()
返回一个线程安全的ArrayList
类,也可以使用concurrent并发包
下的CopyOnWriteArrayList
类。
小结
ArrayList
有三个构造方法,无参构造方法构造的ArrayList
的容量默认为10Arrays.copyof()
内部调用的实际就是System.arraycopy
方法,每次扩容1.5倍
ArrayList
基于数组实现,通过下标索引直接查找到指定位置的元素,因此查找效率高
,但每次插入或删除元素
,就要大量地移动元素,插入删除元素的效率低
。