JDK1.8 Vector实现原理

介绍

Vector是一个可动态扩展的线性表,底层实现是数组。 它的实现原理以及使用方式和ArrayList基本一致,不同点就是Vector是线程安全类,ArrayList非线程安全。

 

实现原理

增加元素:

 public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }

在数组中,下标elementCount+1的位置添加一个元素,elementCount表示当前数组中实际存放元素的个数。

删除元素:

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 */
    }

删除数组中指定index的位置的元素,操作步骤是将index+1到size-1之间的元素全部往前移动一位,即index+1到size-1的元素移动到下标为index到size-2的位置。

查询元素:

   public synchronized E get(int index) {
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);
​
        return elementData(index);
    }

根据索引获取数组中的元素值。

修改元素:

   public synchronized E set(int index, E element) {
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);
​
        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }

根据index找到数组中已经存在的元素,然后将新的元素值赋值过去覆盖旧的值,同时将旧的值返回回去。

以上实现原理与ArrayList一致,具体详情请参考ArrayList部分,唯一的区别是在实现时通过synchronized对函数进行加锁来实现线程安全。

迭代器实现

迭代器遍历:

public void testVector(){
        Vector<String> vector = new Vector<>();
        vector.add("A");
        vector.add("B");
        vector.add("C");
        vector.add("D");
        vector.add("E");
        removeElement(vector, "D");
    }
​
public void removeElement(Vector vector, String element){
        Iterator iterator = vector.iterator();
        while (iterator.hasNext()){
            String e = (String)iterator.next();
            if (e.equals(element)){
                iterator.remove();
                break;
            }
        }
    }

当遍历集合时,首先通过调用集合的iterator()方法获得迭代器对象,然后使用hashNext()方法判断集合中是否存在下一个元素,如果存在,则调用next()方法将元素取出,否则说明已到达了集合末尾,停止遍历元素。 特别是对删除操作,由于数组删除一个元素后,数组长度会变,导致无法通过下标对数组进行完整的遍历。

迭代器的源码解析

迭代器的属性:

 private class Itr implements Iterator<E> {
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;
        ...
   }

cursor游标,用来指向数组中下一个元素

lastRet指向遍历到的当前元素,初始值为-1

expectedModCount 表示数组修改的次数,它与modCount进行对比,如果修改次数不一致,就认为失败,用来定位快速失败。

Iterator.hasNext()实现

public boolean hasNext() {
            // Racy but within spec, since modifications are checked
            // within or after synchronization in next/previous
            return cursor != elementCount;
        }

cursor游标与elementCount数组元素个数相等,则表示已经遍历到了数组尾部

Iterator.next()实现

public E next() {
            synchronized (Vector.this) {
                checkForComodification();
                int i = cursor;
                if (i >= elementCount)
                    throw new NoSuchElementException();
                cursor = i + 1;
                return elementData(lastRet = i);
            }
        }

Iterator.remove()实现

public void remove() {
            if (lastRet == -1)
                throw new IllegalStateException();
            synchronized (Vector.this) {
                checkForComodification();
                Vector.this.remove(lastRet);
                expectedModCount = modCount;
            }
            cursor = lastRet;
            lastRet = -1;
        }

删除下标为lastRet对应的元素,把lastRet的值赋值给cursor,lastRet重置为-1。

Iterator迭代器对象在遍历集合时,内部采用指针的方式来跟踪集合中的元素,接下来通过一个图例来演示Iterator对象迭代元素的过程

Iterator没有使用前,lastRet指示器指向index为-1;cursor指向index为0的位置。

遍历步骤:

  1. 将cursor值保存到临时变量i中,cursor指向下一个元素,即cursor=cursor+1

  2. 将i的值赋给lastRet

图示如下:

执行: iterator.next()

执行: iterator.next()

执行: iterator.next()

执行: iterator.next()

最后遍历到数组尾部(cursor与elementCount相等), 通过iterator完成对vector的遍历。其他容器ArrayList,LinkedList的遍历也类似。​

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值