Stack&Vector源码分析 jdk1.6

参照:http://www.cnblogs.com/tstd/p/5104099.html

Stack(Fitst In Last Out)

1、定义

public  class Stack<E> extends Vector<E> {
public class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable

Vector是List的一个实现类,基于数组。扩容为*2。其功能和实现代码和ArrayList基本一样,Vector是线程安全的,ArrayList不是。应为Vector在每一个方法上都加了synchronized,但是效率不高,不推荐。

更好的方案,Collections.synchronizedList()。

2、Stack && Vector底层存储

// 底层使用数组存储数据
    protected Object[] elementData;
    // 元素个数
    protected int elementCount ;
    // 自定义容器扩容递增大小
    protected int capacityIncrement ;

    public Vector( int initialCapacity, int capacityIncrement) {
        super();
        // 越界检查
        if (initialCapacity < 0)
            throw new IllegalArgumentException( "Illegal Capacity: " +
                                               initialCapacity);
        // 初始化数组
        this.elementData = new Object[initialCapacity];
        this.capacityIncrement = capacityIncrement;
    }

    // 使用synchronized关键字锁定方法,保证同一时间内只有一个线程可以操纵该方法
    public synchronized boolean add(E e) {
        modCount++;
       // 扩容检查
       ensureCapacityHelper( elementCount + 1);
        elementData[elementCount ++] = e;
        return true;
    }

    private void ensureCapacityHelper(int minCapacity) {
        // 当前元素数量
        int oldCapacity = elementData .length;
        // 是否需要扩容
        if (minCapacity > oldCapacity) {
           Object[] oldData = elementData;
           // 如果自定义了容器扩容递增大小,则按照capacityIncrement进行扩容,否则按两倍进行扩容(*2)
           int newCapacity = (capacityIncrement > 0) ?
              (oldCapacity + capacityIncrement) : (oldCapacity * 2);
           if (newCapacity < minCapacity) {
              newCapacity = minCapacity;
           }
           // 数组copy
            elementData = Arrays.copyOf( elementData, newCapacity);
       }
    }

3、peek()获取栈顶的对象

/**
     * 获取栈顶的对象,但是不删除
     */
    public synchronized E peek() {
        // 当前容器元素个数
        int   len = size();

        // 如果没有元素,则直接抛出异常
        if (len == 0)
           throw new EmptyStackException();
        // 调用elementAt方法取出数组最后一个元素(最后一个元素在栈顶)
        return elementAt(len - 1);
    }

    /**
     * 根据index索引取出该位置的元素,这个方法在Vector中
     */
    public synchronized E elementAt(int index) {
        // 越界检查
        if (index >= elementCount ) {
           throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
       }

        // 直接通过数组下标获取元素
        return (E)elementData [index];
    }

4、pop()弹栈

/**
     * 弹栈,获取并删除栈顶的对象
     */
    public synchronized E pop() {
        // 记录栈顶的对象
       E      obj;
        // 当前容器元素个数
        int   len = size();

       // 通过peek()方法获取栈顶对象
       obj = peek();
       // 调用removeElement方法删除栈顶对象
       removeElementAt(len - 1);

       // 返回栈顶对象
        return obj;
    }

    /**
     * 根据index索引删除元素
     */
    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) {
           // 进行数组移动,中间删除了一个,所以将后面的元素往前移动(这里直接移动将index位置元素覆盖掉,就相当于删除了)
           System. arraycopy(elementData, index + 1, elementData, index, j);
       }
        // 容器元素个数减1
        elementCount--;
        // 将容器最后一个元素置空(因为删除了一个元素,然后index后面的元素都向前移动了,所以最后一个就没用了 )
        elementData[elementCount ] = null; /* to let gc do its work */
    }

5.push(E item)——压栈(入栈)

/**
     * 将对象添加进容器并返回
     */
    public E push(E item) {
       // 调用addElement将元素添加进容器
       addElement(item);
       // 返回该元素
        return item;
    }

    /**
     * 将元素添加进容器,这个方法在Vector中
     */
    public synchronized void addElement(E obj) {
        modCount++;
       // 扩容检查
       ensureCapacityHelper( elementCount + 1);
       // 将对象放入到数组中,元素个数+1
        elementData[elementCount ++] = obj;
    }

6.search(Object o)——返回对象在容器中的位置,栈顶为1

/**
     * 返回对象在容器中的位置,栈顶为1
     */
    public synchronized int search(Object o) {
        // 从数组中查找元素,从最后一次出现
        int i = lastIndexOf(o);

        // 因为栈顶算1,所以要用size()-i计算
        if (i >= 0) {
           return size() - i;
       }
        return -1;
    }

原文地址:https://www.cnblogs.com/L-a-u-r-a/p/8516877.html

时间: 2024-10-12 01:47:47

Stack&Vector源码分析 jdk1.6的相关文章

Vector 源码分析 jdk1.8

Vector简介 Vector 是矢量队列,它是JDK1.0版本添加的类.继承于AbstractList,实现了List, RandomAccess, Cloneable这些接口.Vector 继承了AbstractList,实现了List:所以,它是一个队列,支持相关的添加.删除.修改.遍历等功能.Vector 实现了RandmoAccess接口,即提供了随机访问功能.RandmoAccess是java中用来被List实现,为List提供快速访问功能的.在Vector中,我们即可以通过元素的序

给jdk写注释系列之jdk1.6容器(10)-Stack&amp;Vector源码解析

前面我们已经接触过几种数据结构了,有数组.链表.Hash表.红黑树(二叉查询树),今天再来看另外一种数据结构:栈. 什么是栈呢,我就不找它具体的定义了,直接举个例子,栈就相当于一个很窄的木桶,我们往木桶里放东西,往外拿东西时会发现,我们最开始放的东西在最底部,最先拿出来的是刚刚放进去的.所以,栈就是这么一种先进后出( First In Last Out,或者叫后进先出) 的容器,它只有一个口,在这个口放入元素,也在这个口取出元素. 栈最主要了两个动作就是入栈和出栈操作,其实还是很容易的明白的对不

Stack和Vector源码分析

Stack和Vector源码分析 Stack和Vector源码分析stack源码分析1.Stack是什么2.Stack的结构图3.Stack继承关系4.Stack的主要方法5.Stack源码Vector源码分析1.vector介绍2.vector的关系图3.vector和ArrayList的关系4.Vector的大致图像5.Vector的源码 stack源码分析 1.Stack是什么 Stack是栈.它的特性是:先进后出(FILO, First In Last Out). java工具包中的St

ArrayList、LinkedList和Vector源码分析

ArrayList.LinkedList和Vector源码分析 ArrayList ArrayList是一个底层使用数组来存储对象,但不是线程安全的集合类 ArrayList的类结构关系 public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { } ArrayList实现了List接口,List

Java集合之Vector源码分析

概述 Vector与ArrayLIst类似, 内部同样维护一个数组, Vector是线程安全的. 方法与ArrayList大体一致, 只是加上 synchronized 关键字, 保证线程安全, 下面就不具体分析源码了, 具体可以查看ArrayList中的源码分析. Vector源码分析 1.主要字段 2.构造函数 3.增删改查 其他方法大部分类似, 不再赘述, 下面看下扩容机制的函数: Vector与ArrayList的区别 Vector是线程安全的, ArrayList不是线程安全的, 这是

LinkedList源码分析--jdk1.8

JDK1.8 ArrayList源码分析--jdk1.8LinkedList源码分析--jdk1.8 LinkedList概述 ??1.LinkedList是用双向链表实现的集合,基于内部类Node<E>实现的集合.??2.LinkedList支持双向链表访问.克隆.序列化,元素有序且可以重复.??3.LinkedList没有初始化大小,也没有扩容机制,通过头结点.尾节点迭代查找. LinkedList数据结构 ??数据结构是集合的精华所在,数据结构往往也限制了集合的作用和侧重点,了解各种数据

HashMap源码分析--jdk1.8

JDK1.8 ArrayList源码分析--jdk1.8LinkedList源码分析--jdk1.8HashMap源码分析--jdk1.8 HashMap概述 ??1. HashMap是可以动态扩容的数组,基于数组.链表.红黑树实现的集合.??2. HashMap支持键值对取值.克隆.序列化,元素无序,key不可重复value可重复,都可为null.??3. HashMap初始默认长度16,超出扩容2倍,填充因子0.75f.??4.HashMap当链表的长度大于8的且数组大小大于64时,链表结构

AQS源码分析--jdk1.8

JDK1.8 ArrayList源码分析--jdk1.8LinkedList源码分析--jdk1.8HashMap源码分析--jdk1.8AQS源码分析--jdk1.8 AbstractQueuedSynchronizer概述 ??1. AQS是一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.??2. AQS提供了双向链表.??3. AQS分为共享模式和独占模式.??4.AQS基于volatile内存可见性和CAS原子性操作实现线程间通信操作. AbstractQueuedS

ReentrantLock源码分析--jdk1.8

JDK1.8 ArrayList源码分析--jdk1.8LinkedList源码分析--jdk1.8HashMap源码分析--jdk1.8AQS源码分析--jdk1.8ReentrantLock源码分析--jdk1.8 ReentrantLock概述 ??1. ReentrantLock是独占锁.??2. ReentrantLock分为公平模式和非公平模式.??3. ReentrantLock锁可重入(重新插入) ReentrantLock源码分析 /** * @since 1.5 * @aut