首页 > 代码库 > 深入集合类系列——ArrayList和Vector的区别
深入集合类系列——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 = http://www.mamicode.com/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 =http://www.mamicode.com/ c.toArray(); 32 // 得到集合的大小 33 size = elementData.length; 34 // c返回的如果不是object[]数组,则显式转换 35 if (elementData.getClass() != Object[].class) { 36 elementData = http://www.mamicode.com/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 =http://www.mamicode.com/ 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 =http://www.mamicode.com/ 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=http://www.mamicode.com/Arrays.copyOf(elementData,size); 256 } 257 } 258 259 @Override 260 public int size() { 261 // TODO Auto-generated method stub 262 return 0; 263 } 264 }
深入集合类系列——ArrayList和Vector的区别