java中的堆 Stack
package java.util;
public class Stack extends Vector {
public Stack() {
}
public E push(E item) {
addElement(item);
return item;
}
public synchronized E pop() {
E obj;
int len = size();
obj = peek();
removeElementAt(len - 1);
return obj;
}
public synchronized E peek() {
int len = size();
if (len == 0)
throw new EmptyStackException();
return elementAt(len - 1);
}
public boolean empty() {
return size() == 0;
}
public synchronized int search(Object o) {
int i = lastIndexOf(o);
if (i >= 0) {
return size() - i;
}
return -1;
}
}
Stack类 继承了Vector类
public class Vector
extends AbstractList
implements List, RandomAccess, Cloneable, java.io.Serializable
通过阅读Vector类源码 发现
Vector方法大多数被synchronized修饰,线程安全
protected Object[] elementData;
实际用来保存数据的是一个Object数组,java的数组是不可变的,但是Vector确实不受长度限制的,这究竟是为什么呢?我们来看一下add()方法便能知道原因
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}
可以看到 在对elementData进行赋值操作之前,执行了ensureCapacityHelper方法
private void ensureCapacityHelper(int minCapacity) {
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
找到原因了吧, 当要操作的index大小超过elementData现在的大小时会执行grow方法, 这个方法会对elementData进行调整,生成一个新数组,并将原数组的值拷贝过去
获取 get(index) 调用
E elementData(int index) {
return (E) elementData[index];
}
indexOf 没啥难度 不看了
public synchronized int indexOf(Object o, int index) {
if (o == null) {
for (int i = index ; i < elementCount ; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = index ; i < elementCount ; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
接下来看删除方法
删除方法也都大同小异 只看remove方法
public synchronized E remove(int index) {
modCount++;
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
E oldValue = elementData(index);
int numMoved = elementCount - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--elementCount] = null; // Let gc do its work
return oldValue;
}
可以看到 System.arraycopy 会将index+1后面的值复制到index往后的位置,然后将elementCount位置的值改成空,并对elementCount进行--操作
##我们可以看到 Stack类本身只有5个方法,并且调用的都是父类的方法
peek() 查看栈顶值 同步
push() 压栈 同步
pop() 出栈 同步
empty() 查看大小是否为0
search() 查找 同步
Stack的简单应用