标签:
1 public 2 class Stack<E> extends Vector<E> {
我们发现Stack继承了Vector,Vector又是什么东东呢,看一下。
1 public class Vector<E> 2 extends AbstractList<E> 3 implements List<E>, RandomAccess, Cloneable, java.io.Serializable
发现没有,Vector是List的一个实现类,其实Vector也是一个基于数组实现的List容器,其功能及实现代码和ArrayList基本上是一样的。那么不一样的是什么地方的,一个是数组扩容的时候,Vector是*2,ArrayList是*1.5+1;另一个就是Vector是线程安全的,而ArrayList不是,而Vector线程安全的做法是在每个方法上面加了一个synchronized关键字来保证的。但是这里说一句,Vector已经不官方的(大家公认的)不被推荐使用了,正式因为其实现线程安全方式是锁定整个方法,导致的是效率不高,那么有没有更好的提到方案呢,其实也不能说有,但是还真就有那么一个,Collections.synchronizedList(),这不是我们今天的重点不做深入探讨,回到Stack的实现上。
1 // 底层使用数组存储数据 2 protected Object[] elementData; 3 // 元素个数 4 protected int elementCount ; 5 // 自定义容器扩容递增大小 6 protected int capacityIncrement ; 7 8 public Vector( int initialCapacity, int capacityIncrement) { 9 super(); 10 // 越界检查 11 if (initialCapacity < 0) 12 throw new IllegalArgumentException( "Illegal Capacity: " + 13 initialCapacity); 14 // 初始化数组 15 this.elementData = new Object[initialCapacity]; 16 this.capacityIncrement = capacityIncrement; 17 } 18 19 // 使用synchronized关键字锁定方法,保证同一时间内只有一个线程可以操纵该方法 20 public synchronized boolean add(E e) { 21 modCount++; 22 // 扩容检查 23 ensureCapacityHelper( elementCount + 1); 24 elementData[elementCount ++] = e; 25 return true; 26 } 27 28 private void ensureCapacityHelper(int minCapacity) { 29 // 当前元素数量 30 int oldCapacity = elementData .length; 31 // 是否需要扩容 32 if (minCapacity > oldCapacity) { 33 Object[] oldData = elementData; 34 // 如果自定义了容器扩容递增大小,则按照capacityIncrement进行扩容,否则按两倍进行扩容(*2) 35 int newCapacity = (capacityIncrement > 0) ? 36 (oldCapacity + capacityIncrement) : (oldCapacity * 2); 37 if (newCapacity < minCapacity) { 38 newCapacity = minCapacity; 39 } 40 // 数组copy 41 elementData = Arrays.copyOf( elementData, newCapacity); 42 } 43 }
1 /** 2 * 获取栈顶的对象,但是不删除 3 */ 4 public synchronized E peek() { 5 // 当前容器元素个数 6 int len = size(); 7 8 // 如果没有元素,则直接抛出异常 9 if (len == 0) 10 throw new EmptyStackException(); 11 // 调用elementAt方法取出数组最后一个元素(最后一个元素在栈顶) 12 return elementAt(len - 1); 13 } 14 15 /** 16 * 根据index索引取出该位置的元素,这个方法在Vector中 17 */ 18 public synchronized E elementAt(int index) { 19 // 越界检查 20 if (index >= elementCount ) { 21 throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount); 22 } 23 24 // 直接通过数组下标获取元素 25 return (E)elementData [index]; 26 }
3.pop()——弹栈(出栈),获取栈顶的对象,并将该对象从容器中删除
1 /** 2 * 弹栈,获取并删除栈顶的对象 3 */ 4 public synchronized E pop() { 5 // 记录栈顶的对象 6 E obj; 7 // 当前容器元素个数 8 int len = size(); 9 10 // 通过peek()方法获取栈顶对象 11 obj = peek(); 12 // 调用removeElement方法删除栈顶对象 13 removeElementAt(len - 1); 14 15 // 返回栈顶对象 16 return obj; 17 } 18 19 /** 20 * 根据index索引删除元素 21 */ 22 public synchronized void removeElementAt(int index) { 23 modCount++; 24 // 越界检查 25 if (index >= elementCount ) { 26 throw new ArrayIndexOutOfBoundsException(index + " >= " + 27 elementCount); 28 } 29 else if (index < 0) { 30 throw new ArrayIndexOutOfBoundsException(index); 31 } 32 // 计算数组元素要移动的个数 33 int j = elementCount - index - 1; 34 if (j > 0) { 35 // 进行数组移动,中间删除了一个,所以将后面的元素往前移动(这里直接移动将index位置元素覆盖掉,就相当于删除了) 36 System. arraycopy(elementData, index + 1, elementData, index, j); 37 } 38 // 容器元素个数减1 39 elementCount--; 40 // 将容器最后一个元素置空(因为删除了一个元素,然后index后面的元素都向前移动了,所以最后一个就没用了 ) 41 elementData[elementCount ] = null; /* to let gc do its work */ 42 }
4.push(E item)——压栈(入栈),将对象添加进容器并返回
1 /** 2 * 将对象添加进容器并返回 3 */ 4 public E push(E item) { 5 // 调用addElement将元素添加进容器 6 addElement(item); 7 // 返回该元素 8 return item; 9 } 10 11 /** 12 * 将元素添加进容器,这个方法在Vector中 13 */ 14 public synchronized void addElement(E obj) { 15 modCount++; 16 // 扩容检查 17 ensureCapacityHelper( elementCount + 1); 18 // 将对象放入到数组中,元素个数+1 19 elementData[elementCount ++] = obj; 20 }
5.search(Object o)——返回对象在容器中的位置,栈顶为1
1 /** 2 * 返回对象在容器中的位置,栈顶为1 3 */ 4 public synchronized int search(Object o) { 5 // 从数组中查找元素,从最后一次出现 6 int i = lastIndexOf(o); 7 8 // 因为栈顶算1,所以要用size()-i计算 9 if (i >= 0) { 10 return size() - i; 11 } 12 return -1; 13 }
6.empty()——容器是否为空
1 /** 2 * 检查容器是否为空 3 */ 4 public boolean empty() { 5 return size() == 0; 6 }
1 import java.util.LinkedList; 2 3 public class LinkedStack<E> { 4 5 private LinkedList<E> linked ; 6 7 public LinkedStack() { 8 this.linked = new LinkedList<E>(); 9 } 10 11 public E push(E item) { 12 this.linked .addFirst(item); 13 return item; 14 } 15 16 public E pop() { 17 if (this.linked.isEmpty()) { 18 return null; 19 } 20 return this.linked.removeFirst(); 21 } 22 23 public E peek() { 24 if (this.linked.isEmpty()) { 25 return null; 26 } 27 return this.linked.getFirst(); 28 } 29 30 public int search(E item) { 31 int i = this.linked.indexOf(item); 32 return i + 1; 33 } 34 35 public boolean empty() { 36 return this.linked.isEmpty(); 37 } 38 }
给jdk写注释系列之jdk1.6容器(10)-Stack&Vector源码解析
标签:
原文地址:http://www.cnblogs.com/tstd/p/5104099.html