1、jdk中的栈
1、jdk种栈的类名为Stack
2、该类继承Vector类
3、Stack没有自身定义的属性,使用的是Vector类中包含的属性:
Object 数组 elementData:用于存储栈数据
int 类型的elementCount:用于记录当前栈中的可用数据的数量
int 类型的capacityIncrement:用于记录数组增容量增长的数量
4、Stack只有一种空参构造函数,
初始化容量使用的的Vector的默认的初始化容量,容量大小为10,容量增增长默认为0
2、栈的入栈方法 push
1、push方法将入栈对象返回
2、push方法调用的是Vector中的addElement(该方法被synchronized修饰)方法
2.1添加的主要流程:
1、判断栈是否已经满了,如果满了扩容,如果没满加入元素,并将elementCount加1
2、栈是否满的判断elementCount+1与elementData的长度进行比较,如果相减大于0,则扩容。
3、扩容后将数据存入栈中
2.2 扩容的规则
首先,扩容后的数组的大小为当前数组大小的二倍。并且数组的最大大小为Integer.MAX_VALUE
然后,新建一个扩容后的数组,并将原来数组中的值复制到新数组中,将elementData指向新数组
2.3 扩容的源码(Vector类中)
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);
}
3、栈的弹出方法 pop
public synchronized E pop();
返回栈顶元素,即数组中的最后一个元素。elementCount减1,并将该位置上值置为null。
4、查看栈顶元素 peek
public synchronized E peek();
返回栈顶元素,即数组中的最后一个元素。
如果栈为空则抛出 空栈异常 EmptyStackException
5、查询元素在栈中的位置
public synchronized int search(Object o);
返回元素从栈顶往下数的第几个元素。该方法从栈顶即(数组的最后一个)向下查找,当查找到返回结果,如果没有找到返回-1;
注意:
该方法只要找到元素就返回,因此如果有多个相同的元素入栈,从栈顶往下数首次出现的编号。
6、案例
结果
7、总结
1、jdk中的栈存储结构是数组,并且采用可变数组来实现。继承Vector
2、由于栈的方法都是synchronized修饰的,因此栈是线程安全的。
3、栈的大小扩容每次都是扩大到当前容量大小的二倍
4、栈只有一个空参构造器,默认栈的大小为10(也是Vector的默认初始化大小)
5、栈的操作有:压栈(push)-- 时间复杂度O(1),弹栈(pop)-- 时间复杂度O(1),查看栈顶元素(peek)-- 时间复杂度O(1),查询最后压栈元素的位置(search)-- 时间复杂度O(n),查看栈是否为空(isEmpty)
6、pop与peek的区别:
pop返回栈顶元素并删除栈顶元素。
peek返回栈顶元素但是不删除栈顶元素。
7、栈的特点是后进先出(LIFO)
该文章是在阅读源码的时候总结编写的,如果有不对的地方请大家多加指正。