zoukankan      html  css  js  c++  java
  • Stack

    1,定义,last-in-first-out(LIFO)

    java.lang.Object
        java.util.AbstractCollection<E>
            java.util.AbstractList<E>
                java.util.Vector<E>
                    java.util.Stack<E>
                    
    public class Stack<E> extends Vector<E> {}

    2,构造函数

    //初始化一个空栈
    public Stack(){}

    3,主要方法

    3.1 入栈

    public E push(E item) {
        addElement(item);
        return item;
    }
    
    public synchronized void addElement(E obj) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = obj;
    }
    //并不是说随便的就是扩容为原来的两倍的
    private void ensureCapacityHelper(int minCapacity) {
        int oldCapacity = elementData.length;
        if (minCapacity > oldCapacity) {
            Object[] oldData = elementData;
            int newCapacity = (capacityIncrement > 0)?(oldCapacity + capacityIncrement) : (oldCapacity*2);
            if(newCapacity < minCapacity) {
                newCapacity = minCapacity;
            }
            elementData = Arrays.copyOf(elementData, newCapacity);            
        }
    }

    注:

    1,调用的Vector的添加方法;

    2,在这里,扩容的时候需要注意:

      2.1:Vector的构造方法是这样的,这里有牵扯到capacityIncrement增长因子的概念,所以在Vector扩容时需要注意,它并不是说随便的就是扩容,也并不一定是原来的两倍的,而且ArrayList也是同理,并不是随便就扩容,也并不一定是原来的两倍的。

    //Vector 相关概念
    protected Object[] elementData;
    protected int elementCount;
    protected int capacityIncrement;//增长因子
    public Vector(int initialCapacity, int capacityIncrement) {
        super();//Vector extends AbstractList...,protected AbstractList() {}
        if(initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);
        this.elementData = new Object[initialCapacity];
        this.capacityIncrement = capacityIncrement;
    }
    
    public Vector(int intialCapacity) {
        this(intialCapacity, 0);//capacityIncrement默认为0
    }
    //这是我们常用的方式,默认大小为10
    public Vector() {
        this(10)
    }
    
    public Vector(Collection<? extends E> c) {
        elementData = c.toArray();
        elementCount = elementData.length;
        // c.toArray might (incorrectly) not return Object[] (see 6260652)
        if(elementData.getClass() != Object[].class) 
            elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
    }

       2.2,:HashMap,是达到了HashMap的阈值threshold(默认: threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);),再去扩容。

    void addEntry(int hash, K key, V value, int bucketIndex) {
    Entry<K, V> e = table[bucketIndex];
    table[bucketIndex] = new Entry<K, V>(hash, key, value, e);
    if(size++ >= threshold)//超过阈值
        resize(2 * table.length);//新容量再具体判断是否
    }

     3.2 出栈

    public synchronized E peek() {
        int len = size();
        if (len == 0)
            throw new EmptyStackException();
        return elementAt(len - 1);
    }
    
    public synchronized void removeElementAt(int index) {
        modCount++;
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
        else if (index < 0)
            throw new ArrayIndexOutBoundsException(index);
        int j = elementCount - index - 1;
        if(j > 0)
            System.arraycopy(elementData, index + 1, elementData, index, j);
        elementCount--;
        elementData[elementCount] = null;/*to let gc do its work*/    
    }
    //本地的方法
    public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);

    注:

    1,出栈,弹出栈顶元素。

    2,方法removeElementAt(int index){...},取出指定位置index的元素,需要修改后的数组重新定位,所以使用了方法System.arraycopy(...){...}方法。

    3,方法System.arraycopy(...){...}是一个native方法

      (使用native关键字说明这个方法是原生函数,是用C/C++语言实现的,然后编译成DLL,由Java去调。 这些函数的实现体在DLL中,JDK的源代码中并不包含。对于不同的平台它们也是不同的。这也是java的底层机制,实际上java就是在不同的平台上调用不同的native方法实现对操作系统的访问的。

      native参考:https://en.wikipedia.org/wiki/Java_Native_Interface;)

    void objArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d,
                               int dst_pos, int length, TRAPS) {
    assert(s->is_objArray(), "must be obj array");
    
    if (!d->is_objArray()) {
      THROW(vmSymbols::java_lang_ArrayStoreException());
    }
    
    // Check is all offsets and lengths are non negative
    if (src_pos < 0 || dst_pos < 0 || length < 0) {
      THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
    }
    // Check if the ranges are valid
    if  ( (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length())
       || (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length()) )   {
      THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
    }
    
    // Special case. Boundary cases must be checked first
    // This allows the following call: copy_array(s, s.length(), d.length(), 0).
    // This is correct, since the position is supposed to be an 'in between point', i.e., s.length(),
    // points to the right of the last element.
    if (length==0) {
      return;
    }
    if (UseCompressedOops) {
      narrowOop* const src = objArrayOop(s)->obj_at_addr<narrowOop>(src_pos);
      narrowOop* const dst = objArrayOop(d)->obj_at_addr<narrowOop>(dst_pos);
      do_copy<narrowOop>(s, src, d, dst, length, CHECK);
    } else {
      oop* const src = objArrayOop(s)->obj_at_addr<oop>(src_pos);
      oop* const dst = objArrayOop(d)->obj_at_addr<oop>(dst_pos);
      do_copy<oop> (s, src, d, dst, length, CHECK);
      }
    }
    View Code

    3.3 查找 

    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(0, 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;
    }

      

  • 相关阅读:
    9.经典进程同步问题
    8.信号量
    7.进程同步之临界区问题
    6.CPU调度
    AIX 10G HA RAC卸载
    HP11.31安装11.2.0.3实施手册
    AIX上安装oracle10g
    习水医院12C RAC 数据库安装文档
    linux 11201(11203) ASM RAC 安装
    如果一个节点重新安装了,处理办法
  • 原文地址:https://www.cnblogs.com/lemon-now/p/5166090.html
Copyright © 2011-2022 走看看