• java提高(8)---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:表明该类具有序列化功能。

     二、构造函数 

    1 // 默认构造函数  
    2 ArrayList()  
    3   
    4 // capacity是ArrayList的默认容量大小。当由于增加数据导致容量不足时,容量会添加上一次容量大小的一半。  
    5 ArrayList(int capacity)  
    6   
    7 // 创建一个包含collection的ArrayList  
    8 ArrayList(Collection<? extends E> collection)  

    三、ArrayList源码解析

      1 import java.util.*;    
      2      
      3  public class ArrayList<E> extends AbstractList<E>    
      4          implements List<E>, RandomAccess, Cloneable, java.io.Serializable    
      5  {    
      6      // 序列版本号    
      7      private static final long serialVersionUID = 8683452581122892189L;    
      8      
      9      // 保存ArrayList中数据的数组    
     10      private transient Object[] elementData;    
     11      
     12      // ArrayList中实际数据的数量    
     13      private int size;    
     14      
     15      // ArrayList带容量大小的构造函数。    
     16      public ArrayList(int initialCapacity) {    
     17          super();    
     18          if (initialCapacity < 0)    
     19              throw new IllegalArgumentException("Illegal Capacity: "+    
     20                                                 initialCapacity);    
     21          // 新建一个数组    
     22          this.elementData = new Object[initialCapacity];    
     23      }    
     24      
     25         // ArrayList构造函数。默认容量是10。    
     26      public ArrayList() {    
     27          this(10);    
     28      }    
     29      
     30         // 创建一个包含collection的ArrayList    
     31      public ArrayList(Collection<? extends E> c) {    
     32          elementData = c.toArray();    
     33          size = elementData.length;    
     34         // c.toArray might (incorrectly) not return Object[] (see 6260652)    
     35          if (elementData.getClass() != Object[].class)    
     36              elementData = Arrays.copyOf(elementData, size, Object[].class);    
     37      }    
     38          
     39         // 添加元素e    
     40      public boolean add(E e) {    
     41         // 确定ArrayList的容量大小    
     42          ensureCapacity(size + 1);  // Increments modCount!!    
     43         // 添加e到ArrayList中    
     44          elementData[size++] = e;    
     45          return true;    
     46      }    
     47      
     48        // 确定ArrarList的容量。    
     49        // 若ArrayList的容量不足以容纳当前的全部元素,设置 新的容量=“(原始容量x3)/2 + 1”    
     50      public void ensureCapacity(int minCapacity) {    
     51        // 将“修改统计数”+1    
     52          modCount++;    
     53          int oldCapacity = elementData.length;    
     54        // 若当前容量不足以容纳当前的元素个数,设置 新的容量=“(原始容量x3)/2 + 1”    
     55          if (minCapacity > oldCapacity) {    
     56              Object oldData[] = elementData;    
     57              int newCapacity = (oldCapacity * 3)/2 + 1;    
     58              if (newCapacity < minCapacity)    
     59                  newCapacity = minCapacity;    
     60              elementData = Arrays.copyOf(elementData, newCapacity);    
     61          }    
     62      }    
     63          
     64        // 返回ArrayList的实际大小    
     65      public int size() {    
     66          return size;    
     67      }    
     68      
     69       // 返回ArrayList是否包含Object(o)    
     70      public boolean contains(Object o) {    
     71          return indexOf(o) >= 0;    
     72      }    
     73           
     74       // 正向查找,返回元素的索引值    
     75      public int indexOf(Object o) {    
     76          if (o == null) {    
     77              for (int i = 0; i < size; i++)    
     78              if (elementData[i]==null)    
     79                  return i;    
     80              } else {    
     81                  for (int i = 0; i < size; i++)    
     82                  if (o.equals(elementData[i]))    
     83                      return i;    
     84              }    
     85              return -1;    
     86          }    
     87      
     88       // 返回ArrayList是否为空    
     89      public boolean isEmpty() {    
     90          return size == 0;    
     91      }    
     92             
     93      
     94       // 返回ArrayList的Object数组    
     95      public Object[] toArray() {    
     96          return Arrays.copyOf(elementData, size);    
     97      }    
     98      
     99       // 返回ArrayList的模板数组。所谓模板数组,即可以将T设为任意的数据类型    
    100      public <T> T[] toArray(T[] a) {    
    101          // 若数组a的大小 < ArrayList的元素个数;    
    102          // 则新建一个T[]数组,数组大小是“ArrayList的元素个数”,并将“ArrayList”全部拷贝到新数组中    
    103          if (a.length < size)    
    104              return (T[]) Arrays.copyOf(elementData, size, a.getClass());    
    105      
    106          // 若数组a的大小 >= ArrayList的元素个数;    
    107          // 则将ArrayList的全部元素都拷贝到数组a中。    
    108          System.arraycopy(elementData, 0, a, 0, size);    
    109          if (a.length > size)    
    110              a[size] = null;    
    111          return a;    
    112      }    
    113      
    114       // 获取index位置的元素值    
    115      public E get(int index) {    
    116       //判断数组是否越界    
    117          RangeCheck(index);    
    118      
    119          return (E) elementData[index];    
    120      }    
    121      
    122       // 将e添加到ArrayList的指定位置    
    123      public void add(int index, E element) {    
    124          if (index > size || index < 0)    
    125              throw new IndexOutOfBoundsException(    
    126              "Index: "+index+", Size: "+size);    
    127      
    128          ensureCapacity(size+1);  // Increments modCount!!    
    129          System.arraycopy(elementData, index, elementData, index + 1,    
    130               size - index);    
    131          elementData[index] = element;    
    132          size++;    
    133      }    
    134      
    135       // 删除ArrayList指定位置的元素    
    136      public E remove(int index) {    
    137          RangeCheck(index);    
    138      
    139          modCount++;    
    140          E oldValue = (E) elementData[index];    
    141      
    142          int numMoved = size - index - 1;    
    143          if (numMoved > 0)    
    144              System.arraycopy(elementData, index+1, elementData, index,    
    145                   numMoved);    
    146          elementData[--size] = null; // Let gc do its work    
    147      
    148          return oldValue;    
    149      }    
    150      
    151        // 删除ArrayList的指定元素    
    152      public boolean remove(Object o) {    
    153          if (o == null) {    
    154                  for (int index = 0; index < size; index++)    
    155              if (elementData[index] == null) {    
    156                  fastRemove(index);    
    157                  return true;    
    158              }    
    159          } else {    
    160              for (int index = 0; index < size; index++)    
    161              if (o.equals(elementData[index])) {    
    162                  fastRemove(index);    
    163                  return true;    
    164              }    
    165          }    
    166          return false;    
    167      }    
    168      
    169        // 清空ArrayList,将全部的元素设为null    
    170      public void clear() {    
    171          modCount++;    
    172      
    173          for (int i = 0; i < size; i++)    
    174              elementData[i] = null;    
    175      
    176          size = 0;    
    177      }    
    178         
    179        // 将ArrayList的“容量,所有的元素值”都写入到输出流中    
    180      private void writeObject(java.io.ObjectOutputStream s)    
    181          throws java.io.IOException{    
    182        // Write out element count, and any hidden stuff    
    183      int expectedModCount = modCount;    
    184      s.defaultWriteObject();    
    185      
    186          // 写入“数组的容量”    
    187          s.writeInt(elementData.length);    
    188      
    189        // 写入“数组的每一个元素”    
    190      for (int i=0; i<size; i++)    
    191              s.writeObject(elementData[i]);    
    192      
    193      if (modCount != expectedModCount) {    
    194              throw new ConcurrentModificationException();    
    195          }    
    196      }    
    197          
    198        // java.io.Serializable的读取函数:根据写入方式读出    
    199        // 先将ArrayList的“容量”读出,然后将“所有的元素值”读出    
    200      private void readObject(java.io.ObjectInputStream s)    
    201          throws java.io.IOException, ClassNotFoundException {    
    202          // Read in size, and any hidden stuff    
    203          s.defaultReadObject();    
    204      
    205          // 从输入流中读取ArrayList的“容量”    
    206          int arrayLength = s.readInt();    
    207          Object[] a = elementData = new Object[arrayLength];    
    208      
    209          // 从输入流中将“所有的元素值”读出    
    210          for (int i=0; i<size; i++)    
    211              a[i] = s.readObject();    
    212      }    
    213  }   

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

        参考博客:Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例

     

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

  • 相关阅读:
    C++ 将对象写入文件 并读取
    IronPython fail to add reference to WebDriver.dll
    How to Capture and Decrypt Lync Server 2010 TLS Traffic Using Microsoft Tools
    .net code injection
    数学系学生应该知道的十个学术网站
    Difference Between Currency Swap and FX Swap
    Swift开源parser
    谈谈我对证券公司一些部门的理解(前、中、后台)[z]
    JDK8记FullGC时候Metaspace内存不会被垃圾回收
    JVM源码分析之JDK8下的僵尸(无法回收)类加载器[z]
  • 原文地址:https://www.cnblogs.com/qdhxhz/p/7994154.html
Copyright © 2020-2023  润新知