一、Vector与ArrayList 的理解
https://www.cnblogs.com/dengrongzhang/p/9371551.html
https://www.cnblogs.com/rnmb/p/6553711.html
-
Vector是线程安全的集合类,ArrayList并不是线程安全的类。Vector类对集合的元素操作时都加了synchronized,保证线程安全。 我感觉这是最大的不同之处
Vector:
public static void main(String[] args) { Vector<String> v = new Vector<String>(); v.add("test"); }/** * Appends the specified element to the end of this Vector. * * @param e element to be appended to this Vector * @return {@code true} (as specified by {@link Collection#add}) * @since 1.2 * 加锁 效率低了 */ public synchronized boolean add(E e) { modCount++; ensureCapacityHelper(elementCount + 1); elementData[elementCount++] = e; return true; }ArrayList:
public static void main(String[] args) { ArrayList<String> al = new ArrayList<String>(); al.add("test"); }/** * Appends the specified element to the end of this list. * * @param e element to be appended to this list * @return <tt>true</tt> (as specified by {@link Collection#add}) * 没有加锁 线程不安全 */ public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } -
Vector与ArrayList本质上都是一个Object[] 数组,ArrayList提供了size属性,Vector提供了elementCount属性,他们的作用是记录集合内有效元素的个数。与我们平常调用的arrayList.size()和vector.size()一样返回的集合内有效元素的个数。
Vector与ArrayList的扩容并不一样,Vector默认扩容是增长一倍的容量,Arraylist是增长50%的容量。 -
Vector与ArrayList的remove,add(index,obj)方法都会导致内部数组进行数据拷贝的操作,这样在大数据量时,可能会影响效率。
-
Vector与ArrayList的add(obj)方法,如果新增的有效元素个数超过数组本身的长度,都会导致数组进行扩容。
-
-
ArrayList
/**
* 初始化大小
*/
private static final int DEFAULT_CAPACITY = 10;
//底层是数组
transient Object[] elementData;
//无参构造函数 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
//带参数构造 这个参数是一个集合 相当于初始化集合
public ArrayList(Collection<? extends E> c) {
//带参构造 参数是int类型 初始化数组的大小 覆盖默认值
public ArrayList(int initialCapacity) {
//数组的长度 int类型 默认是0
private int size;
private void grow(int minCapacity) {
// 旧数组容量
int oldCapacity = elementData.length;
// 新数组容量=旧数组容量+旧数组容量*0.5 (>>1 相当于除以2 速度快)
int newCapacity = oldCapacity + (oldCapacity >> 1);
//如果新容量 小于 最小容量限度(size+1) 新容量设置为minCapacity
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//如果比最大容量int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
//复制到新数组中
elementData = Arrays.copyOf(elementData, newCapacity);
}
//
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // 溢出了 报错 minCapacity 为什么可能小于0 ? 因为Integer.MAX_VALUE+1 会变成负数
throw new OutOfMemoryError();
//返回Integer.MAX_VALUE 或 MAX_ARRAY_SIZE
return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}
//删除
public E remove(int index) {
//检查下标合法性
rangeCheck(index);
//修改次数 这个是为了在同时修改或者迭代器next的时候 报错 ConcurrentModificationException
modCount++;
//获取旧值 需要返回
E oldValue = elementData(index);
//需要移动的数据的总数
// 数据源 开始复制地址 目标 目标存放开始地址 复制的长度
//arraycopy(Object src,int srcPos,Object dest,int destPos,int length)
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
//设置为null 让gc垃圾回去取回收东西~~
elementData[--size] = null; // clear to let GC do its work
//返回旧值
return oldValue;
}
//检查下标是否越界
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
//越界打印信息 这就是我们常常看到的 输出的越界报错信息 神奇
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+size;
}
//修改指定下标的值
public E set(int index, E element) {
//检查下标合法性
rangeCheck(index);
//获取旧值
E oldValue = elementData(index);
//设置新值
elementData[index] = element;
//返回旧值
return oldValue;
}
//指定位置添加元素
public void add(int index, E element) {
//下标合法性
rangeCheckForAdd(index);
//检查数组长度是否需要增容 modCount加1
ensureCapacityInternal(size + 1);
//复制数组 把index这个地方留下来
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
//修改指定下标位置的数据
elementData[index] = element;
size++;
}
其实简单看这些源码不是很难 但是想要再深入了解 那肯定就会有点儿难度