Stack源码分析
Stack
继承自Vector
,Stack
本身的方法很少,大多数都是依赖父类Vector
的。
构造方法
public Stack() {
}
功能方法
empty
public boolean empty() {
return isEmpty();
}
// Vector.java
@Override
public synchronized boolean isEmpty() {
return elementCount == 0;
}
- 判断是否为空,直接调用父类。
- 因为
Stack
本身是没有什么属性的,只有一个序列号id
。精华都在Vector
身上。Stack
只是针对栈的特性增加了如:peek
/pop
等方法
peek
@SuppressWarnings("unchecked")
public synchronized E peek() {
try {
return (E) elementData[elementCount - 1];
} catch (IndexOutOfBoundsException e) {
throw new EmptyStackException();
}
}
peek
方法返回数组的最后一个元素- 栈的特性就是:先进后出或后进先出。
- 因此,最后进来的元素一定是最先出去的。
push
public E push(E object) {
addElement(object);
return object;
}
// Vector.java
public synchronized void addElement(E object) {
// 1.如果容量已满,就进行数组扩容
if (elementCount == elementData.length) {
growByOne();
}
// 2.在数组最后添加元素
elementData[elementCount++] = object;
modCount++;
}
push
方法也是调用父类的方法实现。- 将元素添加到数组最后。
Stack
的方法已经确定了,只能从数组的尾端进行存/取操作。
search
public synchronized int search(Object o) {
final Object[] dumpArray = elementData; // 存储元素的数据
final int size = elementCount; // 元素的个数
if (o != null) { // 如果要查的数据不为null
for (int i = size - 1; i >= 0; i--) { // 从数组尾部开始向前遍历
if (o.equals(dumpArray[i])) { // 遇到相同的就返回
return size - i;
}
}
} else { // 如果要查的数据为null
for (int i = size - 1; i >= 0; i--) { // 从数组尾部开始向前遍历
if (dumpArray[i] == null) { // 遇到相同的就返回
return size - i;
}
}
}
return -1;
}
- 与
Vector
里的contains
和indexOf
等方法的实现方式类似。
pop
@SuppressWarnings("unchecked")
public synchronized E pop() {
if (elementCount == 0) {
throw new EmptyStackException();
}
final int index = --elementCount;
final E obj = (E) elementData[index];
elementData[index] = null;
modCount++;
return obj;
}
- 元素个数
--
,赋值给index。
此时index
就是最后一位元素的索引。 - 取得值
obj,
置为null,
返回obj
与
peek一样都是取得**最后一位元素**,不同的是
pop会取得的同时删除最后一位元素。而
peek`不会。
总结
Stack
与Vector
很像,大部分都是由Vector
实现的。Stack
只不过一招FILO
的规则,自定义了push
/pop
/peek
等方法。- 理解了
Vector
,Stack
看一遍就懂了!