深入集合类系列——ArrayList和Vector的区别

区别:

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来写入到流中。

  1 //底层的arraylist实现了AbstractList类  和四个接口
  2 //list接口、随机访问接口、可克隆接口、序列化接口
  3 public class MyArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
  4
  5     private static final long serialVersionUID = 1L;
  6     // 属性,元素数据
  7     // transient:反序列化的关键字,不可以被serialized的数组
  8     private transient Object[] elementData;
  9     // 数组的大小,即包含的元素的个数
 10     private int size;
 11
 12     // 构造函数1:根据初始大小分配数组
 13     public MyArrayList(int initialCapacity) {
 14         super();
 15         if (initialCapacity < 0) {
 16             System.out.println("初始化失败" + initialCapacity);
 17         }
 18         // 否则按照initialCapacity分配大小
 19         this.elementData = new Object[initialCapacity];
 20     }
 21
 22     // 构造函数2:以10为大小分配数组
 23     public MyArrayList() {
 24         this(10);
 25     }
 26
 27     // 构造函数3:参数为集合collection,集合之间的拷贝
 28     // Collection<? extends E>代表Collection<E>的子类
 29     public MyArrayList(Collection<? extends E> c) {
 30         // 把集合中的元素赋值给属性集合
 31         elementData = c.toArray();
 32         // 得到集合的大小
 33         size = elementData.length;
 34         // c返回的如果不是object[]数组,则显式转换
 35         if (elementData.getClass() != Object[].class) {
 36             elementData = Arrays.copyOf(elementData, size, Object[].class);
 37         }
 38     }
 39
 40     // 保证数组的容量,确保不会越界
 41     public void ensureCapacity(int minCapacity) {
 42         // 该变量来自AbstractList,表示被修改的次数
 43         modCount++;
 44         // 原来数组的容量
 45         int oldCapacity = elementData.length;
 46         // 如果新的容量更大,则需要重新分配
 47         if (minCapacity > oldCapacity) {
 48             // 赋值出新的数组
 49             Object oldData[] = elementData;
 50             // 构造出新的数组容量,增加原有容量的50%
 51             int newCapacity = (oldCapacity * 3) / 2 + 1;
 52             // 如果新构造出的容量比参数minCapacity要小,则赋值大小和数组本身
 53             if (newCapacity < minCapacity) {
 54                 newCapacity = minCapacity;
 55                 elementData = Arrays.copyOf(elementData, newCapacity);
 56             }
 57         } // end of if
 58             // 当然,如果新的容量比老的容量小,则上面的if判断不会执行。
 59     }
 60
 61     // 在尾部添加一个元素
 62     public boolean add(E e) {
 63         // 保证容量
 64         ensureCapacity(size + 1);
 65         // 赋值新的元素
 66         elementData[size++] = e;
 67         return true;
 68     }
 69
 70     // 在指定位置处插入元素
 71     public void add(int index, E element) {
 72         if (index > size || index < 0) {
 73             System.out.println("数组越界");
 74         }
 75         // 调整容量
 76         ensureCapacity(size + 1);
 77         // 元素拷贝
 78         /*
 79          * 将elementData从index开始的元素赋值到index+1,复制的大小为size-index.也即将index后的元素整体后移动
 80          */
 81         System.arraycopy(elementData, index, elementData, index + 1, size - index);
 82         // 将element指向到index处
 83         elementData[index] = element;
 84         size++;
 85     }
 86
 87     // 将一个集合中的所有元素拷贝到elementData中
 88     public boolean addAll(Collection<? extends E> c) {
 89         // 将集合c转换成Object类型的数组
 90         Object[] a = c.toArray();
 91         // 得到数组的长度
 92         int numNew = a.length;
 93         // 调整容量
 94         ensureCapacity(size + numNew);
 95         // 数组拷贝
 96         System.arraycopy(a, 0, elementData, size, numNew);
 97         // 原有大小增加
 98         size += numNew;
 99         return numNew != 0;
100     }
101
102     // 在指定的位置,将一个集合中的元素拷贝到另外一个集合
103     public boolean addAll(int index, Collection<? extends E> c) {
104         if (index < 0 || index > size) {
105             System.out.println("数组越界");
106         }
107
108         Object[] a = c.toArray();
109         int newNum = a.length;
110         ensureCapacity(size + newNum);
111
112         // 原有数据向后移动多少呢?
113         int movedNum = size - index;
114         if (movedNum > 0) {
115             System.arraycopy(elementData, index, elementData, index + newNum, movedNum);
116         }
117         System.arraycopy(a, 0, elementData, index, newNum);
118         size += newNum;
119         return newNum != 0;
120     }
121
122     // 清空数组的内容,元素置Null 大小清0
123     public void clear() {
124         modCount++;
125         for (int i = 0; i < size; i++) {
126             elementData[i] = null;
127         }
128         size = 0;
129     }
130
131     // 浅拷贝
132     public Object clone() {
133         try {
134             MyArrayList<E> v = (MyArrayList<E>) super.clone();
135             v.elementData = Arrays.copyOf(elementData, size);
136             v.modCount = 0;
137             return v;
138         } catch (CloneNotSupportedException e) {
139             // TODO Auto-generated catch block
140             throw new InternalError();
141         }
142     }
143
144     // 返回对象在arraylist中的索引
145     public int indexOf(Object o) {
146         // 如果对象为null
147         if (o == null) {
148             for (int i = 0; i < size; i++) {
149                 if (elementData[i] == null) {
150                     return i;
151                 }
152             }
153         } else {
154             for (int i = 0; i < size; i++) {
155                 if (o.equals((elementData)[i])) {
156                     return i;
157                 }
158             }
159         }
160         return -1;
161     }
162
163     // 是否包含一个对象
164     public boolean contains(Object o) {
165         return indexOf(o) >= 0;
166     }
167
168     // 返回出现对象的最后一次索引
169     // 从后向前遍历arraylist
170     public int lastIndexOf(Object o) {
171         if (o == null) {
172             for (int i = size - 1; i >= 0; i--) {
173                 if (elementData[i] == null) {
174                     return i;
175                 }
176             }
177         } else {
178             for (int i = size - 1; i >= 0; i--) {
179                 if (o.equals(elementData[i])) {
180                     return i;
181                 }
182             }
183         }
184         return -1;
185     }
186
187     // 取得指定索引处的元素值
188     public E get(int index) {
189         RangeCheck(index);
190         return (E) elementData[index];
191     }
192
193     // 越界检查的方法
194     public void RangeCheck(int index) {
195         if (index >= size || index < 0) {
196             System.out.println("取值非法!");
197         }
198     }
199
200     // 删除指定位置处的元素,并返回该元素
201     public E remove(int index) {
202         // 边界检查
203         RangeCheck(index);
204         modCount++;
205         // 取得旧的元素
206         E oldelement = (E) elementData[index];
207         int numMoved = size - index - 1;
208         if (numMoved > 0) {
209             System.arraycopy(elementData, index + 1, elementData, index, numMoved);
210         }
211         elementData[--size] = null;
212         return oldelement;
213     }
214
215     // 判断移除是否成功
216     public boolean remove(Object o) {
217         if (o == null) {
218             for (int index = 0; index < size; index++)
219                 if (elementData[index] == null) {
220                     fastRemove(index);
221                     return true;
222                 }
223         } else {
224             for (int index = 0; index < size; index++)
225                 if (o.equals(elementData[index])) {
226                     fastRemove(index);
227                     return true;
228                 }
229         }
230         return false;
231     }
232
233     //快速移除的方法
234     private void fastRemove(int index) {
235         modCount++;
236         int numMoved = size - index - 1;
237         if (numMoved > 0)
238             System.arraycopy(elementData, index+1, elementData, index,
239                              numMoved);
240         elementData[--size] = null; // Let gc do its work
241     }
242
243
244     //转换成对象数组
245     public Object[] toArray(){
246         return Arrays.copyOf(elementData,size);
247     }
248
249     //调整数组的大小
250     public void trimToSize(){
251         modCount++;
252         int oldCapacity = elementData.length;
253         if(size<oldCapacity){
254             //按照size的大小拷贝出一个数组,较少空间的使用
255             elementData=Arrays.copyOf(elementData,size);
256         }
257     }
258
259     @Override
260     public int size() {
261         // TODO Auto-generated method stub
262         return 0;
263     }
264 }
时间: 2024-10-22 17:42:05

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

深入解析 Java集合类ArrayList与Vector的区别

集合类分为两个分支,Collection与Map,其中Collection接口继承了Iterator接口,继承Iterator接口的类可以使用迭代器遍历元素(即Collection接口的类都可以使用),今天我们从相同点.不同点.以及JDK源码等各个方面来深入解析下,底层使用数组实现的两个集合类:ArrayList与Vector的区别与联系 区别与联系: 1.ArrayList出现于jdk1.2,vector出现于1.0.两者底层的数据存储都使用的Object数组实现,因为是数组实现,所以具有查找

ArrayList和Vector的区别

这两个类都实现了List接口(List接口继承了Collection接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的数组,我们以后可以按位置索引号取出某个元素,,并且其中的数据是允许重复的,这是HashSet之类的集合的最大不同处,HashSet之类的集合不可以按索引号去检索其中的元素,也不允许有重复的元素(本来题目问的与hashset没有任何关系,但为了说清楚ArrayList与Vector的功能,我们使用对比方式,更有利于说明问题). 接着才说Arra

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

ArrayList和Vector的区别?从两个方面 1.同步性:ArrayList是线程不安全的,是非同步的:Vector是线程安全的,是同步的.(Java中线程的同步也就满足了安全性) 2.数值增长:ArrayList每次增长为原来的50%;Vector每次增长为原来的100%; (从内部实现机制来讲,ArrayList和Vector都是使用数组(Array)来控制集合中的对象,当向集合中添加对象时,如果内部数组长度不够用时,长度会自动增长.ArrayList会增长为原来的1.5倍,Vecto

ArrayList 和 Vector 的区别

这两个类都实现了 List 接口( List 接口继承了 Collection 接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的数组,我们以后可以按位置索引号取出某个元素,,并且其中的数据是允许重复的,这是 HashSet 之类的集合的最大不同处, HashSet 之类的集合不可以按索引号去检索其中的元素,也不允许有重复的元素(本来题目问的与 hashset 没有任何关系,但为了说清楚 ArrayList 与 Vector 的功能,我们使用对比方式,更有利

ArrayList和Vector的区别?

首先两个类都实现了List接口.他们都是有序不唯一的集合,说白了就是存储元素的位置是有序的(每一个元素都以一个对应的索引),相当于一个动态数组 ArrayList和Vector的区别,主要包括两个方面 同步性: Vector是线程安全的,也就是说它的方法直线是线程同步的,而ArrayList是线程不安全的,它的方法之间是线程不同步的 如果只有一个线程去访问集合那么使用ArrayList,他不考虑线程安全的问题,所以效率会高一些 如果是多个线程去访问集合,那么使用Vector 数据增长性: Arr

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

boolean add(E e) 将指定的元素添加到此列表的尾部. void add(int index, E element) 将指定的元素插入此列表中的指定位置. boolean addAll(Collection<? extends E> c) 按照指定 collection 的迭代器所返回的元素顺序,将该 collection 中的所有元素添加到此列表的 尾部. boolean addAll(int index, Collection<? extends E> c) 从指定

集合ArrayList和Vector的区别?

这两个类都实现了list接口(list接口继承Collection接口),他们都是有序集合(及储存在两个集合中的元素的位置都是有顺序的) . 1.同步性: Vector是线程安全的,也就是说是它的方法之间是线程同步的,而ArrayList是线程序不安全的,它的方法之间是线程不同步的.如果只有一个线程会访问到集合,那最好是使用ArrayList,因为它不考虑线程安全,效率会高些:如果有多个线程会访问到集合,那最好是使用Vector,因为不需要我们自己再去考虑和编写线程安全的代码. 2.数据增长:

hashmap和hashtable,arraylist和vector的区别

hashmap线程不安全,hashtable线程安全 hashmap允许使用 null 值和 null 键.(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同.)此类不保证映射的顺序,特别是它不保证该顺序恒久不变. hashtable任何非 null 对象都可以用作键或值.为了成功地在哈希表中存储和获取对象,用作键的对象必须实现 hashCode 方法和 equals 方法. arraylist线程不安全,vector线程安全 arraylist和vect

Java集合类(2)--ArrayList和Vector的比较

相同点: 这两个类都实现了 List 接口( List 接口继承了 Collection 接口),他们都是有序集合(是指能够保持加入时的顺序),元素允许重复. 不同点: (1)  Vector 是线程安全,ArrayList 是线程序不安全,只有一个线程会访问到集合,那最好是使用ArrayList因为它不考虑线程安全,效率会高些,多个线程会访问到集合,那最好是使用 Vector. (2)  数据增长导致扩容时,Vector 增长量为原来的1倍, ArrayList 增长量为原来的0.5倍