数据结构之栈原理(Vector)

栈接口

  • public E push(E item);
  • public synchronized E pop();
  • public synchronized E peek();
  • public boolean empty();
  • public synchronized int search(Object o);

底层实现是Vector

public class Stack extends Vector {…}
采用是继承的方式,也就是说Stack也可以使用Vector其他方法。
在这里插入图片描述

Vector分析

构造方法

  • 创建一个空的Vector,并且指定了Vector的初始容量为10
public Vector() {
        this(10);
    }
  • 创建一个空的Vector,并且指定了Vector的初始容量
public Vector(int initialCapacity) {
        this(initialCapacity, 0);
    }
  • 创建一个空的Vector,并且指定了Vector的初始容量和扩容时的增长系数
public Vector(int initialCapacity, int capacityIncrement) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
        this.capacityIncrement = capacityIncrement;
    }

添加元素

  • 尾部添加
public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }
public synchronized void addElement(E obj) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = obj;
    }
  • 指定位置添加
public void add(int index, E element) {
        insertElementAt(element, index);
    }
public synchronized void insertElementAt(E obj, int index) {
        modCount++;
        if (index > elementCount) {
            throw new ArrayIndexOutOfBoundsException(index
                                                     + " > " + elementCount);
        }
        ensureCapacityHelper(elementCount + 1);
        System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
        elementData[index] = obj;
        elementCount++;
    }

删除元素

  • 删除指定位置的元素
public synchronized E remove(int index) {
        modCount++;
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);
        E oldValue = elementData(index);

        int numMoved = elementCount - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--elementCount] = null; // Let gc do its work

        return oldValue;
    }
public synchronized void removeElementAt(int index) {
        modCount++;
        if (index >= elementCount) {
            throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                                     elementCount);
        }
        else if (index < 0) {
            throw new ArrayIndexOutOfBoundsException(index);
        }
        int j = elementCount - index - 1;
        if (j > 0) {
            System.arraycopy(elementData, index + 1, elementData, index, j);
        }
        elementCount--;
        elementData[elementCount] = null; /* to let gc do its work */
    }
  • 根据元素值来删除元素
public boolean remove(Object o) {
        return removeElement(o);
    }
public synchronized boolean removeElement(Object obj) {
        modCount++;
        int i = indexOf(obj);
        if (i >= 0) {
            removeElementAt(i);
            return true;
        }
        return false;
    }

修改元素

public synchronized E set(int index, E element) {
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);

        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }
public synchronized void setElementAt(E obj, int index) {
        if (index >= elementCount) {
            throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                                     elementCount);
        }
        elementData[index] = obj;
    }

查找元素

  • 查询Vector容器中是否包含某个元素
public boolean contains(Object o) {
        return indexOf(o, 0) >= 0;
    }
  • 查询第n次出现的指定元素的索引
public synchronized int indexOf(Object o, int index) {
        if (o == null) {
            for (int i = index ; i < elementCount ; i++)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = index ; i < elementCount ; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }
public synchronized int lastIndexOf(Object o, int index) {
        if (index >= elementCount)
            throw new IndexOutOfBoundsException(index + " >= "+ elementCount);

        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;
    }
  • 查找某个索引位置的值
public synchronized E get(int index) {
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);

        return elementData(index);
    }
public synchronized E elementAt(int index) {
        if (index >= elementCount) {
            throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
        }

        return elementData(index);
    }
  • 查找首尾位置的值
public synchronized E firstElement() {
        if (elementCount == 0) {
            throw new NoSuchElementException();
        }
        return elementData(0);
    }
public synchronized E lastElement() {
        if (elementCount == 0) {
            throw new NoSuchElementException();
        }
        return elementData(elementCount - 1);
    }

遍历

for(String string:t){
	System.err.print(string);
}
t.forEach(new Consumer<String>(){
	@Override
	public void accept(String t){
		System.out.print(t);
	}
});
//效率最高
for(int i=0;i<t.size();i++){
	System.out.print(t.get(i))
}
Iterator<String> it = t.Iterator();
while(it.hasNext()){
	String string = (String)it.next();
	System.err.print(string);
}
Enumeration<String> enume = t.elements();
while(enume.hasMoreElements()){
	System.out.print(enume.nextElement().toString());
}

扩容机制

private void ensureCapacityHelper(int minCapacity) {
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
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);
    }
private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

Vector与其他容器的区别

  • Vector是线程安全的,ArrayList是线程非安全的
  • Vector默认是初始容量为10的数组,ArrayList默认是空数组
  • ArrayList扩容的新容量是增长1.5倍
  • Vector可以指定增长因子,新的数组等于原数组加上增长因子
  • 如果Vector不指定增长因子,那么就给原数组大小*2
  • Vector的indexOf增加了索引,可以在指定位置开始搜索

Vector的线程安全问题

Vector根据源码分析是线程安全的,它其中大多数方法都加了synchronized,保证线程安全,但是只是局部安全而已,全局来看还是不安全的。

vector的使用主要有如下两种场景:
(1)vector所谓的多线程安全,只是针对单纯地调用某个方法它是有同步机制的。如add,多个线程都在对同一个容器add元素,vector能够保证最后总数是正确的,而ArrayList没有同步机制,就无法保证。
(2)vector的多线程安全,在组合操作时不是线程安全的。比如一个线程先调用vector的size方法得到有10个元素,再调用get(9)方法获取最后一个元素,而另一个线程调用remove(9)方法正好删除了这个元素,那第一个线程就会抛越界异常。

总结:
(1)在需要对容器进行组合操作时,vector不适用(需要自己用synchronized将组合操作进行同步);
(2)仅在上述第一种场景时,才需要使用vector

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值