通常情况下,我们要操作几个数据的时候想到的是数组,但是由于数组它的容量大小是固定,而我们想要的是动态可增长的数组,所以,可以使用java中的集合类,实际上,集合类的底层也是数组写的。 类型object类型
今天学习的是集合中的Arraylist
定义:
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable
它是可调整大小的数组的实现List接口。 实现所有可选列表操作,并允许所有元素,包括null 。 除了实现List 接口之外,该类还提供了一些方法来操纵内部使用的存储列表的数组的大小。 (这个类是大致相当于Vector,不同之处在于它是不同步的)。
每个ArrayList实例都有一个容量 。 容量是用于存储列表中的元素的数组的大小。 它总是至少与列表大小一样大。 当元素添加到ArrayList时,其容量会自动增长。
Arraylist的扩容和缩容问题,也就是存值和取值的时候。Arrays.copyOf方法和remove 方法
Arraylist存放的元素是有序,线程是不安全的。
扩容的时候,Arraylist的初始扩容为10。
transient Object[] elementData;
private void ensureExplicitCapacity(int minCapacity) {
modCount++;// overflow-conscious code
// 判断是否需要扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}扩容底层使用Arrays.copyOf方法
remove 方法:
arraylist集合删除 是否需要考虑缩容 问题 需要缩容的问题
基于元素内容删除时间复杂度就是为o(n)private void fastRemove(int index) {
modCount++;
16-10-1 =5
###计算删除index 后面所有元素有多少个
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
}
注意点:
modCount++; 多线程的情况下 A线程在遍历数据 B线程在继续存放数据
Arraylist与Vector集合有那些区别
相同点:都是基于数组实现 、默认初始容量为10
不同点:
1. Arraylist线程不安全 Vector线程是安全
2. 扩容Arraylist 1.5倍 Vector2倍capacityIncrement自己可以设置扩容的值
当多线程的遍历的时候,可以看见,其中forEach的底层实现这里,其中modCount就是多线程情况下判断的标志,发生改变,它直接就出来了,这是一个fastclass机制。modCount就是为了防止一边存储,一边取出的操作,尽管如此,Arraylist的线程也是不安全的。