​ 昨天在了解到ArrayList的自动扩容之后,忽然想到在Java的另外一个类-Vector里面,实现了数组的自动增长,然后看源码了解了一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
	/**
* The array buffer into which the components of the vector are
* stored. The capacity of the vector is the length of this array buffer,
* and is at least large enough to contain all the vector's elements.
*
* <p>Any array elements following the last element in the Vector are null.
*
* @serial
*/
protected Object[] elementData;

/**
* The number of valid components in this {@code Vector} object.
* Components {@code elementData[0]} through
* {@code elementData[elementCount-1]} are the actual items.
*
* @serial
*/
protected int elementCount;
有趣的java.util.*List
/**
* The amount by which the capacity of the vector is automatically
* incremented when its size becomes greater than its capacity. If
* the capacity increment is less than or equal to zero, the capacity
* of the vector is doubled each time it needs to grow.
*
* @serial
*/
protected int capacityIncrement;

​ 在Vector内部,通过定义两个int变量来控制一个Vector数组的增长。elementCount指的是当前数组的使用量,capacityIncrement指的是在数组需要增加容量的时候增加的大小,elementData是一个底层的数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
private Object[] grow(int minCapacity) {
return elementData = Arrays.copyOf(elementData,
newCapacity(minCapacity));
}

private Object[] grow() {
return grow(elementCount + 1);
}

/**
* Returns a capacity at least as large as the given minimum capacity.
* Will not return a capacity greater than MAX_ARRAY_SIZE unless
* the given minimum capacity is greater than MAX_ARRAY_SIZE.
*
* @param minCapacity the desired minimum capacity
* @throws OutOfMemoryError if minCapacity is less than zero
*/
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;
}

​ 跟ArrayList没有什么区别,Vector也是好几个方法套来套去实现数组的扩容,套来套去是为了保证代码的实用性和安全性。但是跟ArrayList实现方法不一样的是,在Vector内部,通过capacityIncrement来对数组的扩增进行长度控制,当数组需要扩容时,检查capacityIncrement的值,如果不非零,那么每次扩容都增加capacityIncrement的长度,如果非零,那么每次增加的量是原数组的长度,也就是oldCapacity。capacityIncrement的值是通过在建立一个Vector的时候在构造器中传入的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* Constructs an empty vector with the specified initial capacity and
* capacity increment.
*
* @param initialCapacity the initial capacity of the vector
* @param capacityIncrement the amount by which the capacity is
* increased when the vector overflows
* @throws IllegalArgumentException if the specified initial capacity
* is negative
*/
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;

}

​ 这样子的实现使得Vector成为了可控的自增数组。

ArrayList实现:有趣的java.util.*List

奇妙的设计思想

​ 这段话是我在读完Stack的源码之后加上的。至于为什么加到这里,因为我是真的对JDK的设计思路感到神奇。
Stack,这个栈,我印象中在我学习数据结构的时候,自己创建一个栈,使用了各种绕来绕去的方法,写上两三百行的代码(当然,这个并不包括注释,就算包括,也不会再多太多),这之间可能自己都绕不过来,然后才实现了一个勉强能够使用的Stack类。但是当我看到源码中的Stack,继承了Vector数组,这也是我把这段话写到这里的原因,然后Vector定义了一些极具通用性的方法,然后直接调用,付出的只是些参数,例如Stack的长度,然后就把一个Stack类写完了。哇,神奇的设计思路。