关于java:JDK源码分析Vector

5次阅读

共计 2755 个字符,预计需要花费 7 分钟才能阅读完成。

本文首发于微信公众号【WriteOnRead】,欢送关注。

1. 概述

上文「JDK 源码剖析 -ArrayList」次要剖析了 ArrayList 的实现原理。本文剖析 List 接口的另一个实现类:Vector。

Vector 的外部实现与 ArrayList 相似,也能够了解为一个「可变数组」。其继承构造如下(省略局部接口):

PS: 因为 Vector 目前应用较少,且官网也举荐在无线程平安的需要时应用 ArrayList 代替 Vector,这里仅钻研其实现原理。

stackoverflow 也有相干的探讨:

https://stackoverflow.com/que…

2. 代码剖析

依然从其结构器动手进行剖析。

2.1 结构器

Vector 对外提供四个结构器(外部能够认为是两个),其一:

protected Object[] elementData;

protected int capacityIncrement;

// 无参结构器
public Vector() {this(10);
}

// 指定容量的结构器
public Vector(int initialCapacity) {this(initialCapacity, 0);
}

// 指定初始容量和容量增长因子的结构器
public Vector(int initialCapacity, int capacityIncrement) {super();
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal Capacity:"+
                                           initialCapacity);
    this.elementData = new Object[initialCapacity];
    this.capacityIncrement = capacityIncrement;
}

与 ArrayList 相似,Vector 外部也保护了一个 Object 类型的数组(elementData)来存储元素(默认初始容量也是 10)。不同的是:Vector 比 ArrayList 的结构器多了一个参数 capacityIncrement,该变量也导致了二者的扩容形式略有不同,前面进行剖析。

其二:入参为汇合的结构器

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.2 扩容原理剖析

咱们仍从其 add() 办法动手进行剖析:

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

留神这里的关键字 synchronized。察看能够发现:Vector 外部许多办法都应用了该关键字,这也是 Vector 实现线程平安的形式,简略粗犷!

其扩容办法实现如下:

/**
 * The number of valid components in this {@code Vector} object.
 * Components elementData[0] through
 * elementData[elementCount-1] are the actual items.
 */
protected int elementCount;

/*
 * 该办法是非同步的
 * 因为 Vector 外部调用该办法的中央都应用了 synchronized 关键字进行同步,这里不再额定应用
 */
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 与 ArrayList 的扩容形式基本一致,只是新容量的计算形式有所不同,这里剖析下其新容量大小:

int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity);

Vector 计算扩容后的新容量时,依据 capacityIncrement 的值能够分为两种状况:

  1. capacityIncrement > 0:新容量 = 旧容量 + capacityIncrement;
  2. capacityIncrement <= 0:新容量 = 旧容量 * 2。

3. 线程安全性

Vector 是线程平安的,它实现线程平安的形式也很简略粗犷:间接在办法上应用 synchronized 关键字进行同步。

4. 小结

  1. 与 ArrayList 相似,Vector 也能够认为是「可变数组」;
  2. 扩容原理与 ArrayList 基本一致,只是新容量计算形式略有不同:指定增长容量时,新容量为旧容量 + 增长容量;否则扩容为旧容量的 2 倍;
  3. 线程平安的,实现形式简略(synchronized);
  4. 以后应用较少,这里仅学习其实现原理。

正文完
 0