java提高(8)---ArrayList源码

2年前 (2022) 程序员胖胖胖虎阿
307 0 0

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】

版权声明:程序员胖胖胖虎阿 发表于 2022年9月14日 上午12:48。
转载请注明:java提高(8)---ArrayList源码 | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...