ArrayList集合(一)--源码

ArrayList源码

      一、定义

public class ArrayList<E> extends AbstractList<E> implements List<E>,RandomAccess,Cloneable,java.io.Serializable

从中我们可以了解到:

  • ArrayList<E>:说明ArrayList支持泛型。
  • extends AbstractList<E> :继承了AbstractList。AbstractList提供List接口的骨干实现,以最大限度地减少“随机访问”数据存储(如ArrayList)实现Llist所需的工作。
  • implements List<E>:实现了List。实现了所有可选列表操作。
  • implements RandomAccess:表明ArrayList支持快速(通常是固定时间)随机访问。此接口的主要目的是允许一般的算法更改其行为,从而在将其应用到随机或连续访问列表时能提供良好的性能。
  • implements Cloneable:表明其可以调用clone()方法来返回实例的field-for-field拷贝。
  • implements java.io.Serializable:表明该类具有序列化功能。
    二、构造函数
/ 默认构造函数
ArrayList()

// capacity是ArrayList的默认容量大小。当由于增加数据导致容量不足时,容量会添加上一次容量大小的一半。
ArrayList(int capacity)

// 创建一个包含collection的ArrayList
ArrayList(Collection<? extends E> collection)
  三、ArrayList源码解析
import java.util.*;  
   
 public class ArrayList<E> extends AbstractList<E>  
         implements List<E>, RandomAccess, Cloneable, java.io.Serializable  
 {  
     // 序列版本号  
     private static final long serialVersionUID = 8683452581122892189L;  
   
     // 保存ArrayList中数据的数组  
     private transient Object[] elementData;  
   
     // ArrayList中实际数据的数量  
     private int size;  
   
     // ArrayList带容量大小的构造函数。  
     public ArrayList(int initialCapacity) {  
         super();  
         if (initialCapacity < 0)  
             throw new IllegalArgumentException("Illegal Capacity: "+  
                                                initialCapacity);  
         // 新建一个数组  
         this.elementData = new Object[initialCapacity];  
     }  
   
        // ArrayList构造函数。默认容量是10。  
     public ArrayList() {  
         this(10);  
     }  
   
        // 创建一个包含collection的ArrayList  
     public ArrayList(Collection<? extends E> c) {  
         elementData = c.toArray();  
         size = elementData.length;  
        // c.toArray might (incorrectly) not return Object[] (see 6260652)  
         if (elementData.getClass() != Object[].class)  
             elementData = Arrays.copyOf(elementData, size, Object[].class);  
     }  
       
        // 添加元素e  
     public boolean add(E e) {  
        // 确定ArrayList的容量大小  
         ensureCapacity(size + 1);  // Increments modCount!!  
        // 添加e到ArrayList中  
         elementData[size++] = e;  
         return true;  
     }  
   
       // 确定ArrarList的容量。  
       // 若ArrayList的容量不足以容纳当前的全部元素,设置 新的容量=“(原始容量x3)/2 + 1”  
     public void ensureCapacity(int minCapacity) {  
       // 将“修改统计数”+1  
         modCount++;  
         int oldCapacity = elementData.length;  
       // 若当前容量不足以容纳当前的元素个数,设置 新的容量=“(原始容量x3)/2 + 1”  
         if (minCapacity > oldCapacity) {  
             Object oldData[] = elementData;  
             int newCapacity = (oldCapacity * 3)/2 + 1;  
             if (newCapacity < minCapacity)  
                 newCapacity = minCapacity;  
             elementData = Arrays.copyOf(elementData, newCapacity);  
         }  
     }  
       
       // 返回ArrayList的实际大小  
     public int size() {  
         return size;  
     }  
   
      // 返回ArrayList是否包含Object(o)  
     public boolean contains(Object o) {  
         return indexOf(o) >= 0;  
     }  
        
      // 正向查找,返回元素的索引值  
     public int indexOf(Object o) {  
         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;  
         }  
   
      // 返回ArrayList是否为空  
     public boolean isEmpty() {  
         return size == 0;  
     }  
          
   
      // 返回ArrayList的Object数组  
     public Object[] toArray() {  
         return Arrays.copyOf(elementData, size);  
     }  
   
      // 返回ArrayList的模板数组。所谓模板数组,即可以将T设为任意的数据类型  
     public <T> T[] toArray(T[] a) {  
         // 若数组a的大小 < ArrayList的元素个数;  
         // 则新建一个T[]数组,数组大小是“ArrayList的元素个数”,并将“ArrayList”全部拷贝到新数组中  
         if (a.length < size)  
             return (T[]) Arrays.copyOf(elementData, size, a.getClass());  
   
         // 若数组a的大小 >= ArrayList的元素个数;  
         // 则将ArrayList的全部元素都拷贝到数组a中。  
         System.arraycopy(elementData, 0, a, 0, size);  
         if (a.length > size)  
             a[size] = null;  
         return a;  
     }  
   
      // 获取index位置的元素值  
     public E get(int index) {  
      //判断数组是否越界  
         RangeCheck(index);  
   
         return (E) elementData[index];  
     }  
   
      // 将e添加到ArrayList的指定位置  
     public void add(int index, E element) {  
         if (index > size || index < 0)  
             throw new IndexOutOfBoundsException(  
             "Index: "+index+", Size: "+size);  
   
         ensureCapacity(size+1);  // Increments modCount!!  
         System.arraycopy(elementData, index, elementData, index + 1,  
              size - index);  
         elementData[index] = element;  
         size++;  
     }  
   
      // 删除ArrayList指定位置的元素  
     public E remove(int index) {  
         RangeCheck(index);  
   
         modCount++;  
         E oldValue = (E) elementData[index];  
   
         int numMoved = size - index - 1;  
         if (numMoved > 0)  
             System.arraycopy(elementData, index+1, elementData, index,  
                  numMoved);  
         elementData[--size] = null; // Let gc do its work  
   
         return oldValue;  
     }  
   
       // 删除ArrayList的指定元素  
     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;  
     }  
   
       // 清空ArrayList,将全部的元素设为null  
     public void clear() {  
         modCount++;  
   
         for (int i = 0; i < size; i++)  
             elementData[i] = null;  
   
         size = 0;  
     }  
      
       // 将ArrayList的“容量,所有的元素值”都写入到输出流中  
     private void writeObject(java.io.ObjectOutputStream s)  
         throws java.io.IOException{  
       // Write out element count, and any hidden stuff  
     int expectedModCount = modCount;  
     s.defaultWriteObject();  
   
         // 写入“数组的容量”  
         s.writeInt(elementData.length);  
   
       // 写入“数组的每一个元素”  
     for (int i=0; i<size; i++)  
             s.writeObject(elementData[i]);  
   
     if (modCount != expectedModCount) {  
             throw new ConcurrentModificationException();  
         }  
     }  
       
       // java.io.Serializable的读取函数:根据写入方式读出  
       // 先将ArrayList的“容量”读出,然后将“所有的元素值”读出  
     private void readObject(java.io.ObjectInputStream s)  
         throws java.io.IOException, ClassNotFoundException {  
         // Read in size, and any hidden stuff  
         s.defaultReadObject();  
   
         // 从输入流中读取ArrayList的“容量”  
         int arrayLength = s.readInt();  
         Object[] a = elementData = new Object[arrayLength];  
   
         // 从输入流中将“所有的元素值”读出  
         for (int i=0; i<size; i++)  
             a[i] = s.readObject();  
     }  
 } 


  总结
(01) ArrayList 实际上是通过一个数组去保存数据的。当我们构造ArrayList时;若使用默认构造函数,则ArrayList的默认容量大小是10
(02) 当ArrayList容量不足以容纳全部元素时,ArrayList会重新设置容量:新的容量=“(原始容量x3)/2 + 1
(03) ArrayList的克隆函数,即是将全部元素克隆到一个数组中。
(04) ArrayList实现java.io.Serializable的方式。当写入到输出流时,先写入“容量”,再依次写入“每一个元素”;当读出输入流时,先读取“容量”,再依次读取“每一个元素”。

   参考:
 
    水滴石穿,成功的速度一定要超过父母老去的速度! 少尉【3】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值