Vector和ArrayList类似,内部也是维护一个Object的数组 protected Object[] elementData,也允许null存在.其实现了 List
需要深入了解它,便要从成员变量、构造方法、主要方法深入
protected Object[] elementData; // Vector 内部维护的数组,用来存储数据
protected int elementCount; // 存储元素个数
protected int capacityIncrement; // 扩容时的增加量,大于0 增加capacityIncrement 否则就是扩为 2 倍
private static final long serialVersionUID = -2767605614048989439L;
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
elementCount是实际存储的元素个数, capacityIncrement是增加量,如果增加量大于0 就扩容为 capacityIncrement的值。
就比如可以指定增加量的值大小:capacityIncrement初始化为2,下次扩容时判断capacityIncrement是否大于0 ,大于零就会增加capacityIncrement的容量值(扩容).
List
vector = new Vector<>(1,2);
其中还有一个属性也是比较重要的,不过不是它的,而是它的父类的属性。
protected transient int modCount = 0;
modCount 是ArrayList 继承自 AbstractList 的属性,它是用来记录集合的尺寸被修改次数的,add、remove 方法会导致 modCount +1.
初始化时提供了四个方法
public Vector() public Vector(int initialCapacity) public Vector(int initialCapacity, int capacityIncrement) public Vector(Collection extends E> c)
/** * Constructs an empty vector so that its internal data array * has size {@code 10} and its standard capacity increment is * zero. */ public Vector() { this(10); }
既然无参构造方法中使用有参构造方法 :public Vector(int initialCapacity).默认初始化增量为0
public Vector(int initialCapacity) { this(initialCapacity, 0);// 初始化增量为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; }
初始化elementData数组的容量大小为initialCapacity,并且增量为capacityIncrement.
public Vector(Collection extends E> c) { elementData = c.toArray(); elementCount = elementData.length; // defend against c.toArray (incorrectly) not returning Object[] // (see e.g. https://bugs.openjdk.java.net/browse/JDK-6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, elementCount, Object[].class); }
判断elementData的class类型是否是Object[],不是就做转换。(defend against c.toArray (incorrectly) not returning Object[])
演示扩容机制的代码:
public class TestVector { public static void main(String[] args) { List
vector = new Vector<>(1,2); for (int i = 0; i < 10; i++) { vector.add(i); } vector.add(1); } }
主要通过deburg方式,查看代码执行的过程,当第11次在添加元素1时,查看源码分析过程:
public synchronized boolean add(E e) { modCount++; add(e, elementData, elementCount); return true; }
该方法是一个线程安全的方法,在调用add(e, elementData, elementCount);源码如下:elementCount是当前的数组元素个数.
private void add(E e, Object[] elementData, int s) { if (s == elementData.length) elementData = grow(); elementData[s] = e; elementCount = s + 1; }
判断当前数组元素的个数是否等于最初始化的大小的容量,对elementData数组进行扩容grow()。
//第一步: private Object[] grow() { return grow(elementCount + 1); // 11 } // 第二步: private Object[] grow(int minCapacity) { return elementData = Arrays.copyOf(elementData, newCapacity(minCapacity)); }
真正的扩容newCapacity()方法:
private int newCapacity(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity); if (newCapacity - minCapacity <= 0) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return minCapacity; } return (newCapacity - MAX_ARRAY_SIZE <= 0) ? newCapacity : hugeCapacity(minCapacity); } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
首先获取当前数组的长度length,并且对增量判断(capacityIncrement > 0),无参构造是默认增量为0,因此就扩容为2倍.其中还对扩容后的newCapacity 长度是否超过最大值判断。没有超过就是返回newCapacity ,超过返回Integer.MAX_VALUE 最大值.
Vector是java.util包的一个类,SynchronizedList是java.Collections中的一个静态内部类。
Collections.synchronizedList(List list)方法返回一个线程安全的List。
因此sychronizedList和Vector没有区别,为什么还要提供两种线程安全的List呢??接下来看看Collections.synchronizedList源码
static class SynchronizedCollection
implements Collection , Serializable { private static final long serialVersionUID = 3053995032091335093L; final Collection c; // Backing Collection final Object mutex; // Object on which to synchronize SynchronizedCollection(Collection c) { this.c = Objects.requireNonNull(c); mutex = this; } SynchronizedCollection(Collection c, Object mutex) { this.c = Objects.requireNonNull(c); this.mutex = Objects.requireNonNull(mutex); } //.... }
通过Collections.synchronizedList(List list) 创建一个线程安全的list
List list1 = Collections.synchronizedList(list);
通过deburg方式查看到源码
public static
List synchronizedList(List list) { return (list instanceof RandomAccess ? new SynchronizedRandomAccessList<>(list) : new SynchronizedList<>(list)); }
查看其中方法源码:发现是加了synchronized同步代码块的。并不是所有的方法都是同步代码块的,有些是没有加的,需要手动加上锁,比如ListIterator
public boolean add(E e) { synchronized (mutex) {return c.add(e);} } public boolean remove(Object o) { synchronized (mutex) {return c.remove(o);} }