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> {}

java PaddlePaddle 向量化 java向量类_ci

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类都拥有。