1.Stack is a subclass of Vector, which is a first-in-last-out (FILO) data structure. Stack inherits all the methods of Vector, and then extends five methods of its own: pop(), push(), peek() , empty(), search().
public Stack(): The no-argument constructor for stack.
synchronized E pop(): remove the object on top of the stack and return it as the value of this function
synchronized E peek(): View the top object on the stack, but do not remove it
push(E item): push the object onto the stack
synchronized empty(): determine whether the stack is empty
synchronized int search(Object o): returns the position of the object on the stack, in 1-bit base
It can be seen that pop, peek and search are synchronized, because the internal methods of empty and push call Vector's methods, and Vector is thread-safe.
2. Because Stack inherits Vector, let's see
Source code: protected Object[] elementData;
protected int elementCount
protected int capacityIncrement
private static final int MAX_ARRAY_SIZE = 2147483639
2.1 public E push(E item)
// push an item to the top of the stack public E push(E item) { //Call the method of adding elements in the Vector class addElement(item); return item; } public synchronized void addElement(E obj) { // Implement the Fail-Fast mechanism by recording the modCount parameter modCount++; //Ensure that the size of the stack will not overflow the newly added data ensureCapacityHelper(elementCount + 1); elementData[elementCount++] = obj; } private void ensureCapacityHelper(int minCapacity) { // Prevent overflow. Exceeds the length that the array can hold and needs to be dynamically expanded! ! ! if (minCapacity - elementData.length > 0) grow(minCapacity); } //The key to the dynamic increase of the array is private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; //If it is a Stack, the array expands to twice the original size int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity); //After expanding the array, you need to judge twice //The first time is whether the capacity of the new array is smaller than elementCount + 1 (minCapacity;) if (newCapacity - minCapacity < 0) newCapacity = minCapacity; //The first time is whether the capacity of the new array is larger than the specified maximum limit Integer.MAX_VALUE - 8 //If it is large, the minCapacity is too large and needs to be judged if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); elementData = Arrays.copyOf(elementData, newCapacity); } //Check if the int value of the capacity has overflowed private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }2.2.public synchronized E peek();
// Find the object on top of the stack without removing it from the stack. public synchronized E peek() { int len = size(); if (len == 0) throw new EmptyStackException(); return elementAt(len - 1); } //The method in Vector gets the number of elements in the actual stack public synchronized int size() { return elementCount; } public synchronized E elementAt(int index) { if (index >= elementCount) { //Array subscript out of bounds exception throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount); } //Return the value of the data subscripted as index return elementData(index); } @SuppressWarnings("unchecked") E elementData(int index) { return (E) elementData[index]; }
2.3.public synchronized E pop()
//Remove the object at the top of the stack and return the object as a function value public synchronized E pop() { E obj; int len = size(); obj = peek(); //The value of len-1 is the index of the last number in the array removeElementAt (len - 1); return obj; } //Method in Vector public synchronized void removeElementAt(int index) { modCount++; / / Array subscript out of bounds exception occurs if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount); } else if (index < 0) { throw new ArrayIndexOutOfBoundsException(index); } //The number of elements after index in the array, because of the method called by Stack, j is always 0 int j = elementCount - index - 1; if (j > 0) { // The elements after index in the array are moved forward as a whole (this method is very useful!!) System.arraycopy(elementData, index + 1, elementData, index, j); } elementCount--; elementData[elementCount] = null; /* to let gc do its work */ }2.4.public boolean empty()
public boolean empty() { return size() == 0; }
2.5
// Return the position of the object on the stack, starting at 1. If the object o exists as an item on the stack, the method returns the closest distance to the top of the stack. //The topmost item in the stack is considered to have a distance of 1. public synchronized int search(Object o) { //lastIndexOf returns the last occurrence of a specified string value, //Search from back to front at a specified position in a string int i = lastIndexOf(o); if (i >= 0) { //So the distance from the top of the stack needs to be subtracted return size() - i; } return -1; } //Method in Vector 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); //Null data can be placed in Vector and Stack 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; }