【JDK】JDK源码分析-Vector

时间:2022-12-31 23:21:19

概述

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

Vector 的内部实现与 ArrayList 类似,也可以理解为一个「可变数组」。其继承结构如下(省略部分接口):

【JDK】JDK源码分析-Vector

PS: 由于 Vector 目前使用较少,且官方也推荐在无线程安全的需求时使用 ArrayList 代替 Vector,这里仅研究其实现原理。

* 也有相关的讨论:

https://*.com/questions/1386275/why-is-java-vector-and-stack-class-considered-obsolete-or-deprecated

仍然从其构造器入手进行分析。

构造器

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);
}

扩容原理分析

我们仍从其 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。

线程安全性

Vector 是线程安全的,它实现线程安全的方式也很简单粗暴:直接在方法上使用 synchronized 关键字进行同步。

Vector 小结

1. 与 ArrayList 类似,Vector 也可以认为是「可变数组」;

2. 扩容原理与 ArrayList 基本一致,只是新容量计算方式略有不同:指定增长容量时,新容量为旧容量 + 增长容量;否则扩容为旧容量的 2 倍;

3. 线程安全的,实现方式简单(synchronized);

4. 当前使用较少,这里仅学习其实现原理。

Stay hungry, stay foolish.

【JDK】JDK源码分析-Vector

PS: 本文首发于微信公众号。

【JDK】JDK源码分析-Vector的更多相关文章

  1. JDK Collection 源码分析(2)—— List

    JDK List源码分析 List接口定义了有序集合(序列).在Collection的基础上,增加了可以通过下标索引访问,以及线性查找等功能. 整体类结构 1.AbstractList   该类作为L ...

  2. JDK AtomicInteger 源码分析

    @(JDK)[AtomicInteger] JDK AtomicInteger 源码分析 Unsafe 实例化 Unsafe在创建实例的时候,不能仅仅通过new Unsafe()或者Unsafe.ge ...

  3. 设计模式(十八)——观察者模式(JDK Observable源码分析)

    1 天气预报项目需求,具体要求如下: 1) 气象站可以将每天测量到的温度,湿度,气压等等以公告的形式发布出去(比如发布到自己的网站或第三方). 2) 需要设计开放型 API,便于其他第三方也能接入气象 ...

  4. JDK Collection 源码分析(3)—— Queue

    @(JDK)[Queue] JDK Queue Queue:队列接口,对于数据的存取,提供了两种方式,一种失败会抛出异常,另一种则返回null或者false.   抛出异常的接口:add,remove ...

  5. JDK Collection 源码分析(1)—— Collection

    JDK Collection   JDK Collection作为一个最顶层的接口(root interface),JDK并不提供该接口的直接实现,而是通过更加具体的子接口(sub interface ...

  6. Caffe学习系列(17): caffe源码分析 vector&lt&semi;Blob&lt&semi;Dtype&gt&semi;&ast;&gt&semi;&amp&semi; bottom(转)

    转自:http://blog.csdn.net/qq_14975217/article/details/51524042 Blob:4个维度 n x c x h x w: bottom[0] .bot ...

  7. caffe源码分析 vector&lt&semi;Blob&lt&semi;Dtype&gt&semi;&ast;&gt&semi;&amp&semi; bottom

    Blob:4个维度 n x c x h x w: bottom[0] .bottom[1]代表该层有几个输入. bottom[0]->count(): 输入中,元素的总维数(个数) bottom ...

  8. STL源码分析-vector

    http://note.youdao.com/noteshare?id=55dc651a7489f1413b3a3169401dcf94

  9. Java集合之Vector源码分析

    概述 Vector与ArrayLIst类似, 内部同样维护一个数组, Vector是线程安全的. 方法与ArrayList大体一致, 只是加上 synchronized 关键字, 保证线程安全, 下面 ...

随机推荐

  1. 培训第四天-----jdbc连接oracle

    oracle链接数据库并向tableone插入中一条数据 package com.zjw.db; import java.sql.Connection; import java.sql.DriverM ...

  2. 使用php来访问操作sql server

    使用php来访问操作sql server 在此分成三步走: 第一部:查看配置,下载文件 首先查看自己的php和sql server版本 Php文件输入echo PHP_VERSION  运行脚本就可以 ...

  3. android布局ui

    LinearLayout和RelativeLayout 属性对比 共有属性:java代码中通过btn1关联次控件android:id=”@+id/btn1″ 控件宽度android:layout_wi ...

  4. 构建微服务开发环境3————Java应用的优秀管理工具Maven的下载安装及配置

    [内容指引] 下载安装包: MacOS下Maven的安装及配置: Windows下Maven的安装及配置. 一.下载安装包 进入Maven的官方下载地址:http://maven.apache.org ...

  5. spring中用到哪些设计模式?

    设计模式作为工作学习中的枕边书,却时常处于勤说不用的尴尬境地,也不是我们时常忘记,只是一直没有记忆. Spring作为业界的经典框架,无论是在架构设计方面,还是在代码编写方面,都堪称行内典范.好了,话 ...

  6. SSM框架指的是什么

    SSM(Spring+SpringMVC+MyBatis)框架集由Spring.SpringMVC.MyBatis三个开源框架整合而成, 常作为数据源较简单的web项目的框架. 其中spring是一个 ...

  7. 【转】WPS word 文档中的插入对象 为什么打不开

    点击桌面左下角开始按钮--所有程序,找到wps office文件夹--wps office工具--配置工具--高级--兼容设置,否选兼容第三方软件.

  8. CodeForces892E 可撤销并查集&sol;最小生成树

    http://codeforces.com/problemset/problem/892/E 题意:给出一个 n 个点 m 条边的无向图,每条边有边权,共 Q 次询问,每次给出 ki​ 条边,问这些边 ...

  9. Linux命令(十八) 压缩或解压缩文件和目录 gzip gunzip

    目录 1.命令简介 2.常用参数介绍 3.实例 4.直达底部 命令简介 和 zip 命令类似,gzip 用于文件的压缩,gzip压缩后的文件扩展名为 ".gz",gzip默认压缩后 ...

  10. cocos2d-js 3&period;0 rc2 自定义UI控件组件 例子:能播放动画的MenuItem。MenuItemSprite的bug

    其实总体自定义UI组件都比较简单,尤其是cocos2d-js是开源的,如果有什么不明白的直接看js代码或者C++代码即可.当然js代码基本就够了. 另外,js的ctor函数虽然说是构造函数,但毕竟不是 ...