stack源码解析
Java类:stack栈
stack是一个继承Vector
类用于栈的类
初始化
public Stack() {}
看看父类的构造函数,做了什么操作?
protected Object[] elementData;//数据存储
protected int capacityIncrement;//容量增量
public Vector() {
this(10);
}
/**
* @param initialCapacity 初始化容量,无参构造器中传入的10
*/
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
/**
* @param initialCapacity 初始化容量,上文传入的10
* @param capacityIncrement 容量增量,上文传入的0
*/
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)//指定的构造新数组的大小小于0,这显然是不合理的,所以直接抛出异常
throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
this.elementData = new Object[initialCapacity];//创建一个长度10的新数组
this.capacityIncrement = capacityIncrement;
}
从源码可以看出,stack使用数组存储数据,并且这一切都依靠父类Vector实现
添加元素:java.util.Stack#push
public E push(E item) {
addElement(item);//调用父类Vector方法
return item;
}
父类Vector方法:java.util.Vector#addElement
protected transient int modCount = 0;//记录操作次数
protected int elementCount;//元素数量计数
public synchronized void addElement(E obj) {
modCount++;//操作次数+1
ensureCapacityHelper(elementCount + 1);//传入一个新的容量(原长度+1),构建新数组
elementData[elementCount++] = obj;//向新数组添加对象(调用完此方法时elementCount值已发生改变)
}
protected Object[] elementData;
/**
*
* @param minCapacity 所需最小扩容容量(容纳新元素的最小数组容量),上文传入值:elementCount + 1
*/
private void ensureCapacityHelper(int minCapacity) {
// 验证所需最小扩容容量是否大于旧容量
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;//记录旧容量
// 计算扩容容量,原则上(capacityIncrement = 0为前提)扩容后的容量是原容量2倍
int newCapacity = oldCapacity + ( capacityIncrement > 0 ? capacityIncrement : oldCapacity);
// 如果扩容容量仍然小于所需最小扩容容量,那么扩容容量采用所需最小扩容容量
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
// 如果扩容容量大于数组最大限,用hugeCapacity处理
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
//重新构建一个新数组,并把原数组的值拷贝过去
elementData = Arrays.copyOf(elementData, newCapacity);
}
java.util.Vector#hugeCapacity
public static final int MAX_VALUE = 0x7fffffff; private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); // 如果所需最小扩容容量 大于数组最大限,那么直接采用0x7fffffff,小于则采用Integer.MAX_VALUE - 8 return minCapacity > MAX_ARRAY_SIZE ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
弹出元素:java.util.Stack#pop
public synchronized E pop() {
E obj;
int len = size();//获取数组长度
obj = peek();//获取数组中最后一个位置的对象
removeElementAt(len - 1);//移除最后一个位置的对象
return obj;//返回对象
}
peek
public synchronized E peek() {
int len = size();//获取数组长度
if (len == 0)
throw new EmptyStackException();
return elementAt(len - 1);//获取数组中最后一个位置的对象
}
/**
* 获取数组中最后一个位置的对象 的具体实现
* */
public synchronized E elementAt(int index) {
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
}
return elementData(index);
}
java.util.Vector#size
public synchronized int size() { return elementCount; }
removeElementAt
public synchronized void removeElementAt(int index) {
modCount++;
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " +
elementCount);
}
else if (index < 0) {
throw new ArrayIndexOutOfBoundsException(index);
}
int j = elementCount - index - 1;
if (j > 0) {
System.arraycopy(elementData, index + 1, elementData, index, j);
}
elementCount--;
elementData[elementCount] = null; //将下标所指位置赋值null,弹出元素并不会导致数组容量缩减
}
总结
从整个代码看得出来
- stack是一个由数组实现的先进后出,后进先出的栈结构
- 容量有限制,初始容量10,删除元素并不直接缩减容量
- stack是线程安全的(利用synchronized锁)
- 主要工作由Vector完成
本文来自博客园,作者:勤匠,转载请注明原文链接:https://www.cnblogs.com/JarryShu/articles/18201339
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现