Stack 源码解析

微信社区交流群

⭐ 添加微信:372787553

Stack 源码解析

Stack类代表最先进先出(LIFO)堆栈的对象。 它扩展了类别Vector与五个操作,允许一个向量被视为堆栈。 设置在通常的pushpop操作,以及作为一种方法来peek在堆栈,以测试堆栈是否为empty的方法,以及向search在栈中的项目的方法在顶部项目和发现多远它是从顶部。

⭐ 示例演示

public class Test {
    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        Integer push = stack.push(1);
        boolean empty = stack.empty();
        Integer peek = stack.peek();
        Integer pop = stack.pop();
        int search = stack.search(1);
    }
}


⭐ push 方法

    public E push(E item) {
        addElement(item);

        return item;
    }

    public synchronized void addElement(E obj) {
        modCount++;
        add(obj, elementData, elementCount);
    }
	
	// 这里是调用的 Vector 
    private void add(E e, Object[] elementData, int s) {
        // 当容量相等时进行扩充
        if (s == elementData.length)
            elementData = grow();
        // 底层是object 的数组进行维护
        elementData[s] = e;
        //将长度进行 +1 操作 , elementCount 的默认长度为10
        // 为什么默认长度为10,当我们取看 Vector的源码就可以看出来,如下
        elementCount = s + 1;
    }

	// 构造方法 其默认长度为10
    public Vector() {
        this(10);
    }

	// 重新计算容量
    private Object[] grow() {
        return grow(elementCount + 1);
    }

    private Object[] grow(int minCapacity) {
        int oldCapacity = elementData.length;
        // 从新计算长度
        int newCapacity = ArraysSupport.newLength(oldCapacity,
                minCapacity - oldCapacity, /* minimum growth */
                capacityIncrement > 0 ? capacityIncrement : oldCapacity
                                           /* preferred growth */);
        // 进行copy
        return elementData = Arrays.copyOf(elementData, newCapacity);
    }

    public static int newLength(int oldLength, int minGrowth, int prefGrowth) {
        // assert oldLength >= 0
        // assert minGrowth > 0

        int newLength = Math.max(minGrowth, prefGrowth) + oldLength;
        if (newLength - MAX_ARRAY_LENGTH <= 0) {
            return newLength;
        }
        return hugeLength(oldLength, minGrowth);
    }

    private static int hugeLength(int oldLength, int minGrowth) {
        int minLength = oldLength + minGrowth;
        if (minLength < 0) { // overflow
            throw new OutOfMemoryError("Required array length too large");
        }
        if (minLength <= MAX_ARRAY_LENGTH) {
            return MAX_ARRAY_LENGTH;
        }
        return Integer.MAX_VALUE;
    }

⭐ 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);
    }
    E elementData(int index) {
        return (E) elementData[index];
    }


⭐ pop

    //这里是将peek 后的数据进行删除操作
	public synchronized E pop() {
        E   obj;
        int len = size();

        obj = peek();
        removeElementAt(len - 1);

        return obj;
    }
	
	// 
    public synchronized void removeElementAt(int index) {
        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);
        }
        modCount++;
        elementCount--;
        // 节省空间
        elementData[elementCount] = null; /* to let gc do its work */
    }


⭐ search

    public synchronized int search(Object o) {
        int i = lastIndexOf(o);

        if (i >= 0) {
            return size() - i;
        }
        return -1;
    }

    public synchronized int lastIndexOf(Object o) {
        return lastIndexOf(o, elementCount-1);
    }
	// 这里也很简单, 循环查找与给定元素相等的下标
    public synchronized int lastIndexOf(Object o, int index) {
        if (index >= elementCount)
            throw new IndexOutOfBoundsException(index + " >= "+ elementCount);

        if (o == null) {
            for (int i = index; i >= 0; i--)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = index; i >= 0; i--)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

⭐ 总结

  • 从源码查看,Stack是线程安全的,由 synchronized 控制
  • 后进先出的原则 last-in-first-out 即 LIFO原则
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小杨同学~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值