ArrayList
特点:
- 动态调整大小:默认大小10,超过了会扩大到15,20,30
- 有序集合:添加的元素都是重0索引开始
- 允许重复元素
- 允许空元素
- 随机访问:通过get和set可以访问和修改数据
- 非同步:线程不安全
Vector
特点:单机项目下线程是安全的 其他的特点ArrayList差不多是一样,
1.add(E e)方法
向集合中添加数据
/**
* Appends the specified element to the end of this list.
* 将指定元素附加到此列表的末尾
* @param e element to be appended to this list
* 传入的值
* @return {@code true} (as specified by {@link Collection#add})
*/
public boolean add(E e) {
modCount++;//此列表在结构上被修改的次数
add(e, elementData, size);
return true;
}
/**
* This helper method split out from add(E) to keep method
* bytecode size under 35 (the -XX:MaxInlineSize default value),
* which helps when add(E) is called in a C1-compiled loop.
* 此辅助方法从add(E)中分离出来,以将方法字节码大小保持在35以下(-XX:MaxInlineSize默认
*值),这有助于在C1编译循环中调用add(E)。
*/
private void add(E e, Object[] elementData, int s) {
//1.判断加入的数据数量是否等于集合的初始化数量(默认是10)
if (s == elementData.length)
//2.如果等于进该方法进行扩容
elementData = grow();
//3.s数组索引位置,e添加的值
elementData[s] = e;
size = s + 1;
}
/**
*扩容
*/
private Object[] grow() {
return grow(size + 1);
}
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
* 增加容量,以确保它至少可以容纳最小容量参数指定的元素数量。
* @param minCapacity the desired minimum capacity
* @throws OutOfMemoryError if minCapacity is less than zero
*/
private Object[] grow(int minCapacity) {
//4.将数组默认长度(10)赋值给oldCapacity
int oldCapacity = elementData.length;
if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
//5.新容量为15
//6.旧的容量10,最小增长为1,10右移1为=5(将10转为二进制向右移一位)
int newCapacity = ArraysSupport.newLength(oldCapacity,
minCapacity - oldCapacity, /* minimum growth */
oldCapacity >> 1 /* preferred growth */);
//7.将新的容量放入elementData中
return elementData = Arrays.copyOf(elementData, newCapacity);
} else {
return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
}
}
2.set(int index, E element)方法
向已有的集合中通过索引设置数据
/**
* Replaces the element at the specified position in this list with
* the specified element.
* 将此列表中指定位置的元素替换为指定的元素
* @param index index of the element to replace 要修改的索引位置
* @param element element to be stored at the specified position 要修改的索引位置的值
*/
public E set(int index, E element) {
//1.判断该索引是否在有效索引内
Objects.checkIndex(index, size);
//2.将索引中的旧值去除并返回
E oldValue = elementData(index);
//3.设置新值到旧值的索引位置
elementData[index] = element;
return oldValue;
}
3.remove(Object o)
通过具体的值将集合中对应的值删除,且只会删除匹配到的第一个值
//从该列表中删除指定元素的第一个匹配项(如果存在)
public boolean remove(Object o) {
final Object[] es = elementData;
final int size = this.size;
//查询到的第一个值的索引
int i = 0;
found: {
if (o == null) {
for (; i < size; i++)
if (es[i] == null)
break found;
} else {
for (; i < size; i++)
if (o.equals(es[i]))
break found;
}
return false;
}
//调用删除方法
fastRemove(es, i);
return true;
}
private void fastRemove(Object[] es, int i) {
modCount++;
final int newSize;
if ((newSize = size - 1) > i)
/**
* src: 源数组
* srcPos:源数组中要复制的元素的索引起始位置
* dest:目标数组
* destPos:目标数组中要复制到的元素的索引起始位置
* length:要复制的元素数量
//将一个数组中的部分元素复制到另一个数组中的指定位置
System.arraycopy(es, i + 1, es, i, newSize - i);
es[size = newSize] = null;
}
4.remove(int index)
通过索引删除后其原有数据会重新排列索引
public E remove(int index) {
//判断索引是否越界
Objects.checkIndex(index, size);
final Object[] es = elementData;
@SuppressWarnings("unchecked") E oldValue = (E) es[index];
//删除索引的值
fastRemove(es, index);
return oldValue;
}
5.add(int index, E element)
public void add(int index, E element) {
//1.检查是否越界
rangeCheckForAdd(index);
//2.修改次数加一
modCount++;
final int s;
Object[] elementData;
//3.将size赋值给s,this.elementData赋值给elementData 并判断是否相等
if ((s = size) == (elementData = this.elementData).length)
elementData = grow();
//4.复制数据到新的数据中
System.arraycopy(elementData, index,
elementData, index + 1,
s - index);
elementData[index] = element;
//5.大小加一
size = s + 1;
}
6.contains(Object o)
int indexOfRange(Object o, int start, int end) {
Object[] es = elementData;
if (o == null) {
for (int i = start; i < end; i++) {
if (es[i] == null) {
return i;
}
}
} else {
for (int i = start; i < end; i++) {
if (o.equals(es[i])) {
return i;
}
}
}
return -1;
}