zoukankan      html  css  js  c++  java
  • 深入集合类系列——ArrayList和Vector的区别

    区别:

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

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

     

    arraylist的特点:

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

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

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

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

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

     

    vector的特点:

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

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

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

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

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

    6Vector实现了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 }

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    GCD
    Android仿人人客户端(v5.7.1)——对从服务器端(网络)获取的图片进行本地双缓存处理(编码实现)
    systimestamp
    byte数组之间的赋值,byte和TCHAR数组的赋值
    如何修改hotspot默认信道
    Wifi的密码长度有何限制
    微信心跳机制
    如何内置iperf到手机中
    如何adb shell进入ctia模式
    本周推荐10款免费的网站模板设计
  • 原文地址:https://www.cnblogs.com/jiaqingshareing/p/6156151.html
Copyright © 2011-2022 走看看