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 }

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    HTML DOM 12 表格排序
    HTML DOM 10 常用场景
    HTML DOM 10 插入节点
    HTML DOM 09 替换节点
    HTML DOM 08 删除节点
    HTML DOM 07 创建节点
    022 注释
    024 数字类型
    005 基于面向对象设计一个简单的游戏
    021 花式赋值
  • 原文地址:https://www.cnblogs.com/jiaqingshareing/p/6156151.html
Copyright © 2011-2022 走看看