Vector类
Vector是矢量队列,是JDK1.0版本添加的类,他继承于AbstractList类,实现了接口库List,RandomAccess,和Cloneable。
- Vector实现了List接口,所以它能够提供:增加,删除,修改,遍历等操作。
- Vector实现RandomAccess接口,所以它能够实现快速访问(即通过索引值就能访问得到)。
- Vector实现了Cloneable接口,所以它能够被克隆。
- Vector和ArrayList不同,他的操作是线程安全的。
Vector类和ArrayList类的对比
通过源码分析,我们可以看到,Vector类和ArrayList类基本上是完全相同的,但是又有一些区别。
相同点:
- 1、ArrayList类出现于JDK1.2,而Vector类出现于JDK1.0。两者底层的数据存储都使用的Object数组实现,所以都具有查找快,增删慢的特点。
- 2、继承的类和实现的接口都是一样的,都继承了AbstractList类(继承后可以使用迭代器遍历),实现了RandomAccess(标记接口,标明实现该接口的list支持快速随机访问),cloneable接口(标识接口,合法调用clone方法),serializable(序列化标识接口)。
不同点:
- 1、构造方法。
- ArrayList类的无参构造会首先构造一个空数组,等到添加第一个元素时,会将数组开辟10个空间大小;有参构造则会直接根据指定大小进行开辟数组。
- Vector类的无参构造会直接开辟10个空间大小的数组,并将增长因子设置为0;有参构造则可以根据指定大小开辟数组,并且可以指定增长因子的大小。
- 源码实现:ArrayList类的源码可以查看ArrayList类的内容,这里仅仅看看Vector类的源码。
/**
* Constructs an empty vector with the specified initial capacity and
* capacity increment.
*
* @param initialCapacity the initial capacity of the vector
* @param capacityIncrement the amount by which the capacity is
* increased when the vector overflows
* @throws IllegalArgumentException if the specified initial capacity
* is negative
*/
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}
/**
* Constructs an empty vector with the specified initial capacity and
* with its capacity increment equal to zero.
*
* @param initialCapacity the initial capacity of the vector
* @throws IllegalArgumentException if the specified initial capacity
* is negative
*/
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
/**
* Constructs an empty vector so that its internal data array
* has size {@code 10} and its standard capacity increment is
* zero.
*/
public Vector() {
this(10);
}
/**
* Constructs a vector containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
*
* @param c the collection whose elements are to be placed into this
* vector
* @throws NullPointerException if the specified collection is null
* @since 1.2
*/
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、扩容方式。
- ArrayList类在首次添加元素将数组大小扩大为10个空间之后,以后的扩容操作仅会进行
1.5倍扩容
。 - Vector类中若是不指定增长因子的大小,会进行
2倍扩容
;若指定了增长因子后,仅仅会扩容增长因子大小个空间
,这样可以大大减少空间的浪费。 - 源码实现:ArrayList类的源码可以查看ArrayList类的内容,这里仅仅看看Vector类的源码。
/**
* The maximum size of array to allocate.
* Some VMs reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: Requested array size exceeds VM limit
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
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);
}
- 3、Vector类的增删改查方法的实现结构,与ArrayList类没有区别,但是方法都用了
synchronized
来修饰。也就是说Vector类是线程安全的,当多线程访问Vector时,不会引起各种各样的错误。
所以Vector类和ArrayList类的区别就是:
- Vector类和ArrayList类的底层实现一摸一样,都是允许null值,允许重复,有序的集合。
- Vector类在构造时可以指定增长因子,也就是扩容的大小;如果不指定增长因子,那么就进行
2倍扩容
,而ArrayList类默认进行1.5倍扩容
。 - Vector类线程安全,ArrayList类线程不安全。
- 使用场景:即线程安全问题。
- 在多线程环境下需要考虑安全问题,则选择使用Vector类;不需要考虑安全问题的情况下则使用ArrayList类(原因是:多线程条件下加锁是十分耗时的)。
关于ArrayList类、LinkedList类和Vector类之间的区别可以参考链接。
Stack类
Stack类是对数据结构栈的封装容器,它继承于Vector类,由于Vector类是通过数组实现的,这就意味着,Stack也是通过数组实现的,而非链表。当然,我们也可以将LinkedList当作链栈来使用。
Stack类的继承结构
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> {}
Stack类的常用方法
由于Stack类继承于Vector类,因此它也包含Vector中的全部方法。
- 1、构造方法:Stack类仅仅只有一个构造方法。
/**
* Creates an empty Stack.
*/
public Stack() {
}
- 2、入栈操作。
/**
* Pushes an item onto the top of this stack. This has exactly
* the same effect as:
* <blockquote><pre>
* addElement(item)</pre></blockquote>
*
* @param item the item to be pushed onto this stack.
* @return the <code>item</code> argument.
* @see java.util.Vector#addElement
*/
public E push(E item) {
addElement(item);
return item;
}
- 3、出栈操作。
/**
* Removes the object at the top of this stack and returns that
* object as the value of this function.
*
* @return The object at the top of this stack (the last item
* of the <tt>Vector</tt> object).
* @throws EmptyStackException if this stack is empty.
*/
public synchronized E pop() {
E obj;
int len = size();
obj = peek();
removeElementAt(len - 1);
return obj;
}
- 4、获取栈顶元素。
/**
* Looks at the object at the top of this stack without removing it
* from the stack.
*
* @return the object at the top of this stack (the last item
* of the <tt>Vector</tt> object).
* @throws EmptyStackException if this stack is empty.
*/
public synchronized E peek() {
int len = size();
if (len == 0)
throw new EmptyStackException();
return elementAt(len - 1);
}
- 5、判空操作。
/**
* Tests if this stack is empty.
*
* @return <code>true</code> if and only if this stack contains
* no items; <code>false</code> otherwise.
*/
public boolean empty() {
return size() == 0;
}
- 6、查找元素。
/**
* Returns the 1-based position where an object is on this stack.
* If the object <tt>o</tt> occurs as an item in this stack, this
* method returns the distance from the top of the stack of the
* occurrence nearest the top of the stack; the topmost item on the
* stack is considered to be at distance <tt>1</tt>. The <tt>equals</tt>
* method is used to compare <tt>o</tt> to the
* items in this stack.
*
* @param o the desired object.
* @return the 1-based position from the top of the stack where
* the object is located; the return value <code>-1</code>
* indicates that the object is not on the stack.
*/
public synchronized int search(Object o) {
int i = lastIndexOf(o);
if (i >= 0) {
return size() - i;
}
return -1;
}
Stack类的方法总结:
- 1、Stack类实际上也是通过数组去实现的。
- 执行
push
时(即将元素推入栈中),是通过将元素追加的数组的末尾中。 - 执行
peek
时(即,取出栈顶元素,不执行删除),是返回数组末尾的元素。 - 执行
pop
时(即,取出栈顶元素,并将该元素从栈中删除),是取出数组末尾的元素,然后将该元素从数组中删除。
- 2、Stack类继承于Vector类,意味着Vector类拥有的属性和功能,Stack类都拥有。