01:java.util.Stack<E>

目录

Stack

Stack继承关系​​

Stack继承及依赖图

构造函数

API

Stack

栈(Stack)是动态集合,在删除操作上它所移除的元素是预先设定的。在栈(Stack)中,被删除的元素是最近插入的,因此栈(Stack)实现的是一种后进先出(last-in,first-out,LIFO)策略。在Java中,使用简单的数组来实现其结构,栈(Stack)上的INSERT操作称为压入(PUSH),无元素参数的DELETE操作称为弹出(POP)。----摘自《算法导论 第三版》

Stack继承关系​​

java.lang.Object
↳     java.util.AbstractCollection<E>
   ↳     java.util.AbstractList<E>
       ↳     java.util.Vector<E>
           ↳     java.util.Stack<E>

Stack继承及依赖图

Stack

构造函数

public Stack()

API

public synchronized E peek()
public              E push(E item)
public synchronized E pop()
public synchronized int search(Object o)
public              boolean empty()

注1:Stack是线程安全的,在push操作中虽然未加锁,但内部操作中调用父类Vector的addElement 操作是加锁的,Vector的addElement 操作声明如下。

public synchronized void addElement(E obj)

注2:当调用push操作时,已加载的父类Vector已初始化底层数组,并默认数组长度为10(关于ClassLoader,可查看JVM相关类初始化问题),因此当进行了10次push操作,会触发父类Vector的grow函数进行动态数组增长。 源码如下

/**
     * This implements the unsynchronized semantics of ensureCapacity.
     * Synchronized methods in this class can internally call this
     * method for ensuring capacity without incurring the cost of an
     * extra synchronization.
     *
     * @see #ensureCapacity(int)
     */
    private void ensureCapacityHelper(int minCapacity) {
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

注3:数组Capacity MAX_ARRAY_SIZE=Integer.MAX_ARRAY_SIZE(2^31 - 1) - 8,当栈增长>Integer.MAX_ARRAY_SIZE - 8,则MAX_ARRAY_SIZE就会更替,这是与之前超过默认长度的操作稍有不同。

注4:Stack Search(重要),此操作为线程安全的,这边使用的是父类Vector中lastIndexOf操作,其具体使用for倒序循环来查找出具体位置,时间复杂度为O(n),为此对其三种循环进行测试。

注4---源码如下

import java.util.Iterator;
import java.util.Stack;

/**
 * @Author: zhangzhirong
 * @Description:
 * @Date:Created in 10:49 2018/11/27/027
 * @Modify By:
 **/
public class StackForForEachIteratorTime {

    private static final int COUNT = 1000000;
    private static Stack stack = new Stack();

    public static void init(){
        //初始化,生成对象个数
        for(int i=0;i<COUNT;i++){
            stack.push(i);
        }
    }
    //Iterator遍历
    public static long testIterator(){
        //开始编译执行时间
        long start =System.nanoTime();
        int i;
        Iterator iterator = stack.iterator();
        while ( iterator.hasNext()) {
            i = (int) iterator.next();

        }
        //执行完后的时间
        long end =System.nanoTime();
        return (end- start) / 1000;
    }
    //foEach循环遍历
    public static long testForEach(){
        //开始编译执行时间
        long start =System.nanoTime();
        int i;
        for(Object p:stack){
            i = (int)p;
        }
        //执行完后的时间
        long end =System.nanoTime();
        return (end- start) / 1000;
    }
    //for循环遍历
    public static long testFor(){
        //开始编译执行时间
        long start =System.nanoTime();
        int j;
        for(int i=0;i<stack.size();i++){
            j=(int)stack.pop();
        }
        //执行完后的时间
        long end =System.nanoTime();
        return (end- start) / 1000;
    }

    public static void main(String[] args) {
        init();
        System.out.println("Stack---Iterator迭代遍历的消耗时间为:"+testIterator());
        System.out.println("Stack---ForEach遍历的消耗时间为:"+testForEach());
        System.out.println("Stack---For循环遍历的消耗时间为:"+testFor());

    }
}

注4---测试结果如下

Iterator迭代遍历的消耗时间为:43877
ForEach遍历的消耗时间为:39972
For循环遍历的消耗时间为:40207

Process finished with exit code 0

注4---个人结论:在栈(Stack)内部,for循环遍历在各方面统计消耗更小,因此此源码开发者选取for循环进行查找操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值