Stack
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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); } }
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; }
以上是关于Stack的主要内容,如果未能解决你的问题,请参考以下文章
Android - 在单个活动应用程序中使用工具栏按钮弹出 Back Stack