区别:

1)Vector的方法都是同步的(Synchronized),是线程安全的(thread-safe),而ArrayList的方法不是,由于线程的同步必然要影响性能,因此,ArrayList的性能比Vector好。 
2)当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList只增加50%的大小,这样,ArrayList就有利于节约内存空间。

3)对于Vector、是一个比较古老的类、相对于ArrayList而言、它通过将许多方法使用synchronized修饰来保证线程安全性、但是保证线程安全是要代价的、这也使得他的效率并没有ArrayList高

arraylist的特点:

1、ArrayList 是一个数组队列,相当于 动态数组。与Java中的数组相比,它的容量能动态增长。它继承于AbstractList,实现了List, RandomAccess, Cloneable, java.io.Serializable这些接口。

2、ArrayList 继承了AbstractList,实现了List。它是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。

3、ArrayList 实现了RandmoAccess接口,即提供了随机访问功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在ArrayList中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。稍后,我们会比较List的“快速随机访问”和“通过Iterator迭代器访问”的效率。

4、ArrayList 实现了Cloneable接口,即覆盖了函数clone(),能被克隆。

5、ArrayList 实现java.io.Serializable接口,这意味着ArrayList支持序列化,能通过序列化去传输。

vector的特点:

1、Vector是内部是以动态数组的形式来存储数据的。

2、Vector具有数组所具有的特性、通过索引支持随机访问、所以通过随机访问Vector中的元素效率非常高、但是执行插入、删除时效率比较地下、具体原因后面有分析。

3、Vector实现了AbstractList抽象类、List接口、所以其更具有了AbstractList和List的功能、前面我们知道AbstractList内部已经实现了获取Iterator和ListIterator的方法、所以Vector只需关心对数组操作的方法的实现、

4、Vector实现了RandomAccess接口、此接口只有声明、没有方法体、表示Vector支持随机访问。

5、Vector实现了Cloneable接口、此接口只有声明、没有方法体、表示Vector支持克隆。

6、Vector实现了Serializable接口、此接口只有声明、没有方法体、表示Vector支持序列化、即可以将Vector以流的形式通过ObjectOutputStream来写入到流中。

 //底层的arraylist实现了AbstractList类  和四个接口
//list接口、随机访问接口、可克隆接口、序列化接口
public class MyArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { private static final long serialVersionUID = 1L;
// 属性,元素数据
// transient:反序列化的关键字,不可以被serialized的数组
private transient Object[] elementData;
// 数组的大小,即包含的元素的个数
private int size; // 构造函数1:根据初始大小分配数组
public MyArrayList(int initialCapacity) {
super();
if (initialCapacity < 0) {
System.out.println("初始化失败" + initialCapacity);
}
// 否则按照initialCapacity分配大小
this.elementData = new Object[initialCapacity];
} // 构造函数2:以10为大小分配数组
public MyArrayList() {
this(10);
} // 构造函数3:参数为集合collection,集合之间的拷贝
// Collection<? extends E>代表Collection<E>的子类
public MyArrayList(Collection<? extends E> c) {
// 把集合中的元素赋值给属性集合
elementData = c.toArray();
// 得到集合的大小
size = elementData.length;
// c返回的如果不是object[]数组,则显式转换
if (elementData.getClass() != Object[].class) {
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
} // 保证数组的容量,确保不会越界
public void ensureCapacity(int minCapacity) {
// 该变量来自AbstractList,表示被修改的次数
modCount++;
// 原来数组的容量
int oldCapacity = elementData.length;
// 如果新的容量更大,则需要重新分配
if (minCapacity > oldCapacity) {
// 赋值出新的数组
Object oldData[] = elementData;
// 构造出新的数组容量,增加原有容量的50%
int newCapacity = (oldCapacity * 3) / 2 + 1;
// 如果新构造出的容量比参数minCapacity要小,则赋值大小和数组本身
if (newCapacity < minCapacity) {
newCapacity = minCapacity;
elementData = Arrays.copyOf(elementData, newCapacity);
}
} // end of if
// 当然,如果新的容量比老的容量小,则上面的if判断不会执行。
} // 在尾部添加一个元素
public boolean add(E e) {
// 保证容量
ensureCapacity(size + 1);
// 赋值新的元素
elementData[size++] = e;
return true;
} // 在指定位置处插入元素
public void add(int index, E element) {
if (index > size || index < 0) {
System.out.println("数组越界");
}
// 调整容量
ensureCapacity(size + 1);
// 元素拷贝
/*
* 将elementData从index开始的元素赋值到index+1,复制的大小为size-index.也即将index后的元素整体后移动
*/
System.arraycopy(elementData, index, elementData, index + 1, size - index);
// 将element指向到index处
elementData[index] = element;
size++;
} // 将一个集合中的所有元素拷贝到elementData中
public boolean addAll(Collection<? extends E> c) {
// 将集合c转换成Object类型的数组
Object[] a = c.toArray();
// 得到数组的长度
int numNew = a.length;
// 调整容量
ensureCapacity(size + numNew);
// 数组拷贝
System.arraycopy(a, 0, elementData, size, numNew);
// 原有大小增加
size += numNew;
return numNew != 0;
} // 在指定的位置,将一个集合中的元素拷贝到另外一个集合
public boolean addAll(int index, Collection<? extends E> c) {
if (index < 0 || index > size) {
System.out.println("数组越界");
} Object[] a = c.toArray();
int newNum = a.length;
ensureCapacity(size + newNum); // 原有数据向后移动多少呢?
int movedNum = size - index;
if (movedNum > 0) {
System.arraycopy(elementData, index, elementData, index + newNum, movedNum);
}
System.arraycopy(a, 0, elementData, index, newNum);
size += newNum;
return newNum != 0;
} // 清空数组的内容,元素置Null 大小清0
public void clear() {
modCount++;
for (int i = 0; i < size; i++) {
elementData[i] = null;
}
size = 0;
} // 浅拷贝
public Object clone() {
try {
MyArrayList<E> v = (MyArrayList<E>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
throw new InternalError();
}
} // 返回对象在arraylist中的索引
public int indexOf(Object o) {
// 如果对象为null
if (o == null) {
for (int i = 0; i < size; i++) {
if (elementData[i] == null) {
return i;
}
}
} else {
for (int i = 0; i < size; i++) {
if (o.equals((elementData)[i])) {
return i;
}
}
}
return -1;
} // 是否包含一个对象
public boolean contains(Object o) {
return indexOf(o) >= 0;
} // 返回出现对象的最后一次索引
// 从后向前遍历arraylist
public int lastIndexOf(Object o) {
if (o == null) {
for (int i = size - 1; i >= 0; i--) {
if (elementData[i] == null) {
return i;
}
}
} else {
for (int i = size - 1; i >= 0; i--) {
if (o.equals(elementData[i])) {
return i;
}
}
}
return -1;
} // 取得指定索引处的元素值
public E get(int index) {
RangeCheck(index);
return (E) elementData[index];
} // 越界检查的方法
public void RangeCheck(int index) {
if (index >= size || index < 0) {
System.out.println("取值非法!");
}
} // 删除指定位置处的元素,并返回该元素
public E remove(int index) {
// 边界检查
RangeCheck(index);
modCount++;
// 取得旧的元素
E oldelement = (E) elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0) {
System.arraycopy(elementData, index + 1, elementData, index, numMoved);
}
elementData[--size] = null;
return oldelement;
} // 判断移除是否成功
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
} //快速移除的方法
private void fastRemove(int index) {
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // Let gc do its work
} //转换成对象数组
public Object[] toArray(){
return Arrays.copyOf(elementData,size);
} //调整数组的大小
public void trimToSize(){
modCount++;
int oldCapacity = elementData.length;
if(size<oldCapacity){
//按照size的大小拷贝出一个数组,较少空间的使用
elementData=Arrays.copyOf(elementData,size);
}
} @Override
public int size() {
// TODO Auto-generated method stub
return 0;
}
}

深入集合类系列——ArrayList和Vector的区别的更多相关文章

  1. ArrayList和Vector的区别

    3.ArrayList和Vector的区别 答: 这两个类都实现了List接口(List接口继承了Collection接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种 ...

  2. ArrayList与Vector的区别

    ArrayList与Vector的区别 相同 这两个类都实现了List接口. 他们都是有序集合. 不同 ArrayList实现不是同步的,Vector实现是同步的. ArrayList与Vector都 ...

  3. ArrayList 和 Vector 的区别

    这两个类都实现了 List 接口( List 接口继承了 Collection 接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的数组,我们以后可以按位置索引号取 ...

  4. ArrayList和Vector的区别?

    ArrayList和Vector的区别? 解答:同步性:Vector是线程安全的,也就是说是同步的,而ArrayList是线程不安全的,不是同步的:数据增长:当需要增长时,Vector默认增长为原来一 ...

  5. ArrayList和Vector的区别?HashMap和HashTable的区别?StringBuilder、StringBuffer和String的区别?

    ArrayList和Vector的区别?从两个方面 1.同步性:ArrayList是线程不安全的,是非同步的:Vector是线程安全的,是同步的.(Java中线程的同步也就满足了安全性) 2.数值增长 ...

  6. 一、基础篇--1.2Java集合-ArrayList和Vector的区别

     ArrayList和Vector的区别 ArrayList和Vector都是基于动态数组实现的.  区别 ArrayList是非线程安全的,Vector是线程安全的. Vector的方法都加了同步锁 ...

  7. 【Java面试题】32 ArrayList和Vector的区别

    1. Vector & ArrayList  相同点: 1.ArrayList和Vector都是继承了相同的父类和实现了相同的接口 2.底层都是数组实现的 3.初始默认长度都为10. 不同点: ...

  8. Java中ArrayList和LinkedList区别、ArrayList和Vector的区别

    一般大家都知道ArrayList和LinkedList的大致区别: 1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构. 2.对于随机访问get和set,Ar ...

  9. 集合框架,ArrayList和Vector的区别,让arrayList线程安全的几种方案

    boolean add(E e) 将指定的元素添加到此列表的尾部. void add(int index, E element) 将指定的元素插入此列表中的指定位置. boolean addAll(C ...

随机推荐

  1. JVM宏观认知&&内存结构

    JVM宏观认知 1.什么是虚拟机? 虚拟机是一种软件. 可分为系统虚拟机(仿真物理机)和程序虚拟机(执行单个计算机程序,比如JVM). 2.什么是Java虚拟机(JVM)? JVM是一种将字节码转化为 ...

  2. ZAO 换脸不安全?用 python 轻松实现 AI

    最近两天一款名为 「ZAO」 的 App 刷爆了朋友圈,它的主打功能是 AI 换脸,宣称「只需一张照片,就能出演天下好戏」 : 现实中不能实现当明星的梦,在这个 App 里你可以,想演谁演谁.新鲜.好 ...

  3. 拿 C# 搞函数式编程 - 1

    最近闲下来了,准备出一个 C# 搞 FP 的合集.本合集所有代码均以 C# 8 为示例. 可能你说,为什么要这么做呢?回答:为了好玩.另外,意义党们请 gun cu ke! C# 有委托,而且有 Fu ...

  4. Vue使用MathJax动态识别数学公式

    本人菜鸟一名,如有错误,还请见谅. 1.前言 最近公司的一个项目需求是在前端显示Latex转化的数学公式,经过不断的百度和测试已基本实现.现在此做一个记录. 2.MathJax介绍 MathJax是一 ...

  5. Disruptor框架中生产者、消费者的各种复杂依赖场景下的使用总结

    版权声明:原创作品,谢绝转载!否则将追究法律责任. Disruptor是一个优秀的并发框架,可以实现单个或多个生产者生产消息,单个或多个消费者消息,且消费者之间可以存在消费消息的依赖关系.网上其他博客 ...

  6. SVN分支与主干合并

    1.主干合并到分支 1在本地trunk中先update一下,有冲突的解决冲突,保证trunk和repository已经完全同步, 2.在/branches /MyProject上右键,依次选择”Tor ...

  7. 解决subline安装插件被墙失败的方法

    一.问题场景描述 当你完成subline和package control的安装后,准备使用install package安装各种各样的插件来丰富你的编辑器,却出现类似 “Unable to downl ...

  8. Runtime.getRuntime().exec()实现Java调用python程序

    使用Runtime.getRuntime().exec()来实现Java调用python,调用代码如下所示: import java.io.BufferedReader; import java.io ...

  9. TypeScript模块系统、命名空间、声明合并

    命名空间 命名空间能有效避免全局污染.在ES6引入模块之后,命名空间就较少被提及了.如果使用了全局的类库,命名空间仍是一个好的解决方案. namespace Shape{ const pi = Mat ...

  10. HBase介绍、安装与应用案例

    搭建环境 部署节点操作系统为CentOS,防火墙和SElinux禁用,创建了一个shiyanlou用户并在系统根目录下创建/app目录,用于存放 Hadoop等组件运行包.因为该目录用于安装hadoo ...