29.vector
对于List接口这里还介绍一个它的实现类Vector,Vector 类可以实现可增长的对象数组。
Vector可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的组件。不过,Vector的大小是可以增加或者减小的,以便适应创建Vector后进行添加或者删除操作。
Vector实现List接口,继承AbstractList类,所以我们可以将其看做队列,支持相关的添加、删除、修改、遍历等功能。
Vector实现RandmoAccess接口,即提供了随机访问功能,提供提供快速访问功能。在Vector我们可以直接访问元素。
Vector 实现了Cloneable接口,支持clone()方法,可以被克隆。
Vector提供了四个构造函数:
/**
* 构造一个空向量,使其内部数据数组的大小为 10,其标准容量增量为零。
*/
public Vector() {
this(10);
}
/**
* 构造一个包含指定 collection 中的元素的向量,这些元素按其 collection 的迭代器返回元素的顺序排列。
*/
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);
}
}
/**
* 使用指定的初始容量和等于零的容量增量构造一个空向量。
*/
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;
}
在成员变量方面,Vector提供了elementData , elementCount, capacityIncrement三个成员变量。其中
elementData :"Object[]类型的数组",它保存了Vector中的元素。按照Vector的设计elementData为一个动态数组,可以随着元素的增加而动态的增长,其具体的增加方式后面提到(ensureCapacity方法)。如果在初始化Vector时没有指定容器大小,则使用默认大小为10.
elementCount:Vector
对象中的有效组件数。
capacityIncrement:向量的大小大于其容量时,容量自动增加的量。如果在创建Vector时,指定了capacityIncrement的大小,则,每次当Vector中动态数组容量增加时,增加的大小都是capacityIncrement。如果容量的增量小于等于零,则每次需要增大容量时,向量的容量将增大一倍。
同时Vector是线程安全的!
对于源码的解析,在这里只就增加(add)删除(remove)两个方法进行讲解。
2.1增加:add(E e):将指定元素添加到此向量的末尾。
这个方法相对而言比较简单,具体过程就是先确认容器的大小,看是否需要进行扩容操作,然后将E元素添加到此向量的末尾。
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
//确认容器大小,如果操作容量不够则扩容操作
elementData[elementCount++] = e;
//将e元素添加至末尾
return true;
}
对于Vector整个的扩容过程,就是根据capacityIncrement确认扩容大小的,若capacityIncrement <= 0 则扩大一倍,否则扩大至capacityIncrement 。当然这个容量的最大范围为Integer.MAX_VALUE即,2^32 - 1,所以Vector并不是可以无限扩充的。
private void ensureCapacityHelper(int minCapacity) {
if (minCapacity - elementData.length > 0) {
grow(minCapacity);
}
}
/**
* 进行扩容操作 * 如果此向量的当前容量小于minCapacity,则通过将其内部数组替换为一个较大的数组俩增加其容量。
* 新数据数组的大小将为原来的大小 + capacityIncrement,
* 除非 capacityIncrement 的值小于等于零,在后一种情况下,新的容量将为原来容量的两倍,不过,
*如果此大小仍然小于 minCapacity,则新容量将为 minCapacity。
*/
private void grow(int minCapacity) {
int oldCapacity = elementData.length; //当前容器大小
/* * 新容器大小
* 若容量增量系数(capacityIncrement) > 0,则将容器大小增加到capacityIncrement
* 否则将容量增加一倍
*/
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);
}
/**
* 判断是否超出最大范围
* MAX_ARRAY_SIZE:private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
*/
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) {
throw new OutOfMemoryError();
}
return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}
2.2、remove(Object o)
/**
* 从Vector容器中移除指定元素E
*/
public boolean remove(Object o) {
return removeElement(o);
}
public synchronized boolean removeElement(Object obj) {
modCount++;
int i = indexOf(obj); //计算obj在Vector容器中位置
if (i >= 0) {
removeElementAt(i); //移除
return true;
}
return false;
}
public synchronized void removeElementAt(int index) {
modCount++; //修改次数+1
if (index >= elementCount) {//删除位置大于容器有效大小
throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
} else if (index < 0) {//位置小于 < 0//位置小于 < 0
throw new ArrayIndexOutOfBoundsException(index);
}
int j = elementCount - index - 1;
if (j > 0) {
/**
*从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。
*也就是数组元素从j位置往前移
*/
System.arraycopy(elementData, index + 1, elementData, index, j);
}
elementCount--;//容器中有效组件个数 - 1//容器中有效组件个数 - 1
elementData[elementCount] = null;//将向量的末尾位置设置为null //将向量的末尾位置设置为null
}
因为Vector底层是使用数组实现的,所以它的操作都是对数组进行操作,只不过其是可以随着元素的增加而动态的改变容量大小,其实现方法是是使用
Arrays.copyOf方法将旧数据拷贝到一个新的大容量数组中。Vector的整个内部实现都比较简单,这里就不在重述了。
Vector支持4种遍历方式。
3.1、随机访问
因为Vector实现了RandmoAccess接口,可以通过下标来进行随机访问。
3.2、迭代器
3.2、for循环
3.4、Enumeration循环
Vector vec = new Vector<>();
Enumeration enu = vec.elements();
while (enu.hasMoreElements()) {
value = (Integer)enu.nextElement();
}
以上内容均来自http://www.cnblogs.com/chenssy/博客,此博客为本人学习笔记
29.vector的更多相关文章
- vector 内部方法大全 学习(初学者的参考资料)
1 vector构造函数:也就是如何对一个vector对象进行初始化 ////////////////////////////代码//////////////////////////////// ...
- STL总结之vector
STL中vector是通常作为数组使用,不过它更像一个动态数组,在实际项目开发中大量使用. 优点:存储空间连续,可以使用下标访问,时间复杂度O(1). 缺点:不适合从中间删除和添加元素. C++标准规 ...
- C++ 学习笔记之——STL 库 vector
vector 是一种顺序容器,可以看作是可以改变大小的数组. 就像数组一样,vector 占用连续的内存地址来存储元素,因此可以像数组一样用偏移量来随机访问,但是它的大小可以动态改变,容器会自动处理内 ...
- 【C++】vector容器的用法
检测vector容器是否为空: 1 #include <iostream> 2 #include <string> 3 #include <vector> 4 us ...
- 4-Spark高级数据分析-第四章 用决策树算法预测森林植被
预测是非常困难的,更别提预测未来. 4.1 回归简介 随着现代机器学习和数据科学的出现,我们依旧把从“某些值”预测“另外某个值”的思想称为回归.回归是预测一个数值型数量,比如大小.收入和温度,而分类则 ...
- for_each使用方法详解[转]
for_each使用方法详解[转] Abstract之前在(原創) 如何使用for_each() algorithm? (C/C++) (STL)曾經討論過for_each(),不過當時功力尚淺,只談 ...
- DCM TUTORIAL – AN INTRODUCTION TO ORIENTATION KINEMATICS (REV 0.1)
原英文地址:dcm_tutorial 感觉这篇文章还是很有学习价值的,所以就抽出了一些时间对本文进行的翻译.下面这个好多人用的算法就是一种DCM 滤波器. //==================== ...
- [转]DCM Tutorial – An Introduction to Orientation Kinematics
原地址http://www.starlino.com/dcm_tutorial.html Introduction This article is a continuation of my IMU G ...
- 对于fmri的hrf血液动力学响应函数的一个很直观的解释-by 西南大学xulei教授
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% clear all;clc; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ...
随机推荐
- Java集合中List,Set以及Map等集合体系详解
转载请注明出处:Java集合中List,Set以及Map等集合体系详解(史上最全) 概述: List , Set, Map都是接口,前两个继承至collection接口,Map为独立接口 Set下有H ...
- jdbc导致的问题
遇到的问题:利用eclipse编写web project,Tomcat服务器成功开启,也通过build path导入了jdbc的路径,但是还是出现下面问题 连接数据库代码如下: 连接数据库语句没有问题 ...
- 51单片机学习笔记(清翔版)(21)——ADDA数模转换
A:anolog模拟的 D:digital数字的 AD模拟转数字,DA数字转模拟 生活中的基本都是模拟量,如温度,可以是10℃,10.1℃等 手机的背光亮度自动调节,拿到太阳光下,亮度 ...
- .Net代码控制PrivateBinPath和ConfigurationFile的位置
.Net的WinForm程序有的时候让人很烦的是,在执行目录下总是一大堆的DLL,配置文件,最少则是个以下,多的时候怕有四五十个吧……,自己程序中的类库,第三方的类库……加载一起让人感觉乱糟糟的,非常 ...
- SpringCloud微服务基础
1.传统项目架构 传统项目分为三层架构,将业务逻辑层.数据库访问层.控制层放入在一个项目中.适合于个人或者小团队开发,不适合大团队开发. 2.分布式项目架构(解耦方案) 根据业务需求进行拆分成N个子 ...
- Python-lambda表达式和推导式
lambda表达式和推导式,可实现使用一行语句完成功能开发的效果,减少代码量. 1.lambda表达式 匿名函数,即没有名字的函数 1.1基本语法: lambda argument_list: exp ...
- swift 关于FDFullscreenPopGesture的右滑返回
关于导航栏右滑返回的工具库 FDFullscreenPopGesture 是 OC 版本,用了 runtime 等各种骚操作 关于 swift ,我在 UINavigationController 的 ...
- mkfs.ext4快速格式化大容量硬盘
安装ext4: yum -y install e4fsprogs 使用如下命令可以快速格式化大容量硬盘: mkfs.ext4 -T largefile /dev/xxx
- docker安装nginx和php
参考文章:https://www.cnblogs.com/boundless-sky/p/7182410.html 1.下载镜像docker pull nginxdocker pull php:7.2 ...
- 对DOM,SAX,JDOM,DOM4J四种方法解析XML文件的分析
1.DOM 与平台无关的官方解析方式 DOM是一次性把xml文件加载到内存中,形成一个节点树 对内存有要求 2.SAX java提供的基于事件驱动的解析方式 每次遇到一个标签,会触发相应的事件方法 3 ...