Java中的Vector和Stack底层源码分析
作者:爱喝咖啡的程序员
一. 基本原理和优缺点
Stack继承了Vector,Vector底层还是一个List,也就是基于数组来实现的,所以ArrayList有的优点,比如获取元素的速度快,随机读,它都有,与此相对的,ArrayList的缺点,比如从中间插入一个元素,从中间删除一个元素,Stack也存在。
但是呢,Stack使用最多的方法就是push和pop,换句话说,Stack的作者并非希望我们把使用ArrayList的那一套,直接放到Stack上做。
如果严格按照push和pop来执行,就可以避免中间操作元素时,产生移动元素的后果了。当然了,频繁向Stack push元素,仍然可能导致扩容。
栈和队列(LinkedList)的实现有所不同,栈是"后进先出",而队列是"尾进头出"。
二. 源码分析
2.1 push
Stack底层与ArrayList非常相似,存储数据的容器是数组。
public E push(E item) { addElement(item); return item; }
public synchronized void addElement(E obj) { modCount++; ensureCapacityHelper(elementCount + 1); elementData[elementCount++] = obj; }
private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); elementData = Arrays.copyOf(elementData, newCapacity); }
代码逻辑与ArrayList基本上一样。
首先,判断新增一个元素后,当前的容器能否放得下这么多数据,如果放不下,就要进行扩容。扩容无外乎就是在原有容器的基础上,扩大成1.5倍,如果还是放不下元素,则按照能够容纳新元素的最小大小,作为新容器的大小。只要涉及到扩容,肯定就会使用Arrays.copyOf()。
接着,就是往指定下标的位置,加入新元素。
2.2 pop
弹出栈顶元素。
public synchronized E pop() { E obj; int len = size(); obj = peek(); removeElementAt(len - 1); return obj; }
所谓的栈顶元素,不就是当前数组中最后一个元素么,它的下标就是size-1,所以取出来就好啦。
三. 总结
Stack这个数据结构非常的简单,只要看过ArrayList的源码,再看Stack,2分钟就看完了。
使用栈时,用的最多的就是它"后进先出"的数据结构了。
到此这篇关于Java中的Vector和Stack底层源码分析的文章就介绍到这了,更多相关Vector和Stack底层源码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!