文章目录
(一)List子父层级:
List接口继承Collection,Collection继承于Iterable;
List接口实现类分为:Vector、ArrayList、LinkedList;
(二)List实现类——Vector
1、Vector实现类
(1)Vector底层是一个Object数组,protected Object[] elementData;
(2)Vector中的所有涉及到Object数组的均是会加synchronized,列举常见方法:构造方法、add、remove、get、set等
(3)Vector中的默认容量为10,且扩容默认为当前容量翻倍(直接相加或者构造方法中指定扩容大小)。
2、常见源码:
(1)构造方法:
//无参构造
public Vector() {
this(10);//默认大小为10
}
//初始化指定大小的有参构造方法
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
//指定扩容大小和初始值的有参构造
public Vector(int initialCapacity, int capacityIncrement) {
super();//父类无参构造
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];//实例化存储数组
this.capacityIncrement = capacityIncrement;//设置自动扩容大小
}
(2)add方法:
/*
* 此处列举的直接末尾添加add方法,还有指定位置添加insertElementAt方法添加,操作数组均会在方法上添加synchronized锁
**/
public synchronized boolean add(E e) {
modCount++;//操作次数
ensureCapacityHelper(elementCount + 1);//是否需要扩容
elementData[elementCount++] = e;//存储数据
return true;
}
//扩容判定
private void ensureCapacityHelper(int minCapacity) {
if (minCapacity - elementData.length > 0)//判定是否需要扩容,当前存入值已大于数组大小
grow(minCapacity);//调用扩容方法
}
//数组最大值,使用Integer最大值2147483648-8,因数组需要存自身的元数据占用8位(Class\Lock\Flag\Size)
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
//扩容方法
private void grow(int minCapacity) {
int oldCapacity = elementData.length;//当前数组大小
//根据构造函数判定扩容值,未指定则采用翻一倍方式扩容
int newCapacity = oldCapacity + ((capacityIncrement > 0)?capacityIncrement : oldCapacity);
if (newCapacity - minCapacity < 0)//判定新扩容值是否满足当前存入后的数组大小
newCapacity = minCapacity;//扩容大小不满足,则直接扩容到满足存入后的数组大小
if (newCapacity - MAX_ARRAY_SIZE > 0)//判定扩容后的值是否大于数组最大值
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);//数组迁移复制
}
//存储最大值判定,超出限制则默认使用最大值
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) //越界
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE)?Integer.MAX_VALUE:MAX_ARRAY_SIZE;//返回最大值或者数组最大值
}
(3)remove方法:
/*
* 此处列举的返回boolean值的删除方法,还有直接删除指定索引的remove,
* 它直接在方法上添加synchronized锁,逻辑与具体删除一致
**/
public boolean remove(Object o) {
return removeElement(o);//调用具体删除方法
}
public synchronized boolean removeElement(Object obj) {
modCount++;//操作次数
int i = indexOf(obj);//获取obj在数组中存储的下标,防止数组越界
if (i >= 0) {
removeElementAt(i);//调用删除方法
return true;
}
return false;
}
//索引寻找
public int indexOf(Object o) {
return indexOf(o, 0);//传入需要比对值和数组首标
}
//遍历数组寻找指定值(找寻下标,防止线程不安全,加synchronized)
public synchronized int indexOf(Object o, int index) {
if (o == null) {//判定传入是否为空
for (int i = index ; i < elementCount ; i++)
if (elementData[i]==null)
return i;//返回数组下标第一个为null的索引
} else {
for (int i = index ; i < elementCount ; i++)
if (o.equals(elementData[i]))//判定需要删除值与数组值是否相等,相等则返回第一个相等的下标
return i;//返回索引值
}
return -1;
}
//根据索引对指定下标进行删除(与存储数组进行交互,添加synchronized锁)
public synchronized void removeElementAt(int index) {
modCount++;//操作次数
if (index >= elementCount) {//越界判定
throw new ArrayIndexOutOfBoundsException(index + " >= " +
elementCount);
}else if (index < 0) {//越界判定
throw new ArrayIndexOutOfBoundsException(index);
}
int j = elementCount - index - 1;//计算需要被迁移的数组成员数量
if (j > 0) {
//使用系统类提供的数组复制方法进行迁移复制
//参数说明:被复制的数组,被复制的数组起点下标,目标数组(复制到的新数组),目标数组被复制的起点下标,需要复制的大小
System.arraycopy(elementData, index + 1, elementData, index, j);
}
elementCount--;//成员数量减1
//将原来存储有值的最后一位值置为空,便于GC回收工作,提高内存使用率
elementData[elementCount] = null;
}
(4)get方法:
public synchronized E get(int index) {
if (index >= elementCount)//越界控制
throw new ArrayIndexOutOfBoundsException(index);
return elementData(index);
}
//返回指定数组值
E elementData(int index) {
return (E) elementData[index];
}
(5)set方法:
public synchronized E set(int index, E element) {
if (index >= elementCount)//越界控制
throw new ArrayIndexOutOfBoundsException(index);
E oldValue = elementData(index);//获取索引已存在的值或者null
elementData[index] = element;//设置新值
return oldValue;//返回设置之前的索引数组值
}
3、总结
(1)Vector是线程安全的,每个涉及到存储数据的方法都添加synchronized锁,性能相对会较低;
(2)Vector默认的存储大小为10,不指定自动扩容大小,则默认使用当前数组大小进行自加扩容(直接相加或者构造方法中指定扩容大小);