Jdk8集合源码解析---java.util.Stack

1.Stack的基本介绍

    Stack是一种后进先出(LIFO)的结构,其继承了Vector的基础上拓展5个方法push()、pop()、peek()、empty()、search()而来

a、push(E):将item推入到栈中,依次加入数组中(数组尾部)。

b、pop() :将栈中的最顶一个(数组尾部)item推出,并返回被推出的item

e、peek():返回栈中最顶(数组尾部)的一个item,但不对其做任何操作

d、empty():判断该栈是否为空

e、search(Object):搜索某一个item在该栈中的位置【位置为离栈顶最近的item与栈顶间距离】

 

PS:虽然Java有提供该类型的数据结构,但是官方推荐使用Deque【双端队列】,Deque提供更好的完整性和一致性,应该优先使用。

    Stack基于Vector(Vector的方法用Synchronized修饰的),另外Stack中的pop、peek、search方法夜都是用Synchronized修饰的,所以Stack是线程安全的。

2.Stack的类结构

public class Stack<E> extends Vector<E> {
      ......
}

3.Stack的成员变量

    Stack本身类中没有成员变量,但是因为Stack继承了Vector类,所以咱们得看下Vector的成员变量。

//存储数据的数组
protected Object[] elementData;
//实际存储的元素个数
protected int elementCount;
//扩容的增量值
protected int capacityIncrement;

4.Stack的构造函数

    Stack只有一个构造函数。

public Stack() {}

    由于Stack继承了Vector,所以咱们还得看下Vector的构造函数

public Vector() {
        //默认初始大小是10
        this(10);
}

public Vector(int initialCapacity) {
        //默认增量为0
        this(initialCapacity, 0);
}

public Vector(int initialCapacity, int capacityIncrement) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
        this.capacityIncrement = capacityIncrement;
}

5.Stack的主要方法

5.1添加

public E push(T item);

public E push(E item) {
        //添加元素
        addElement(item);
        //返回添加的元素
        return item;
}

//该方法是Vector的方法
//该方法使用synchronized修饰了,所以是线程安全的
public synchronized void addElement(E obj) {
        //修改次数加一
        modCount++;
        //判断是否需要扩容
        ensureCapacityHelper(elementCount + 1);
        //将被添加的对象放置在elementCount++位置,即size+1
        elementData[elementCount++] = obj;
}

//该方法是Vector的方法
private void ensureCapacityHelper(int minCapacity) {
        //判断是否需要扩容:size+1是否大于当前数组的长度
        if (minCapacity - elementData.length > 0)
            //扩容
            grow(minCapacity);
}

//该方法是Vector的方法
private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        //capacityIncrement为每次扩容的增量
        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);
}

    通过查看源码我们发现Stack的底层数据结构也是数组,可以动态扩容,和ArrayList的底层数据结构是一样的,但是扩容方法有区别,ArrayList一般是扩容至1.5倍,而Stack有个扩容增量值,如果该增量值大于零,新容量值就等于就容量值加上增量值,否则即为旧容量值的两倍。

    5.2.public synchronized E peek();返回栈顶(数组尾部)的元素,但不将其从栈中删除。

public synchronized E peek() {
        //获取当前数组中元素个数
        int len = size();

        if (len == 0)
            throw new EmptyStackException();
        //返回数组尾部元素,所以后进先出
        return elementAt(len - 1);
}

//Vector中的方法
public synchronized E elementAt(int index) {
        if (index >= elementCount) {
            throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
        }

        return elementData(index);
}

//Vector中的方法
E elementData(int index) {
        return (E) elementData[index];
}

    5.3.public synchronized E pop():返回栈顶(数组尾部)的元素,并将其从栈中删除。

public synchronized E pop() {
        E       obj;
        int     len = size();
        //获取数组尾部元素
        obj = peek();
        //将尾部元素删除
        removeElementAt(len - 1);

        return obj;
}

    5.4.public synchronized int search(Object o);

public synchronized int search(Object o) {
        //返回数组中最后一个元素为o的下角标
        int i = lastIndexOf(o);
        
        if (i >= 0) {
            //返回栈顶(数组尾部)与该元素的距离
            return size() - i;
        }
        return -1;
}

    至此,java.util.Stack的基本介绍完成!。

转载于:https://my.oschina.net/u/3765527/blog/1829008

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值