`
这些年
  • 浏览: 389899 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

zy19982004--容器学习七:ArrayList源码分析

 
阅读更多

一.成员变量

Java代码  收藏代码
  1. // 在AbstractList里面定义的  
  2. protected transient int modCount = 0;  
  3.   
  4. // 内部用数组实现  
  5. private transient Object[] elementData;  
  6.   
  7. private int size;  

 

二.构造函数

Java代码  收藏代码
  1. // 自己在写代码的时候为了严谨,最好是先判断参数抛出IllegalArgumentException  
  2. public ArrayList(int initialCapacity) {  
  3.     super();  
  4.     if (initialCapacity < 0)  
  5.         throw new IllegalArgumentException("Illegal Capacity: "  
  6.                 + initialCapacity);  
  7.     this.elementData = new Object[initialCapacity];  
  8. }  
  9.   
  10. // 初始化容量10  
  11. public ArrayList() {  
  12.     this(10);  
  13. }  

 

 三.存数据

Java代码  收藏代码
  1. //增加数据  
  2. public boolean add(E e) {  
  3.     //1.保证容量,size+1和容量比较,看是否有位置插入e  
  4.     ensureCapacity(size + 1); // Increments modCount!!  
  5.     //2.直接赋值  
  6.     elementData[size++] = e;  
  7.     return true;  
  8. }  
  9.   
  10. //在指定位置增加数据  
  11. public void add(int index, E element) {  
  12.     if (index > size || index < 0)  
  13.         throw new IndexOutOfBoundsException("Index: " + index + ", Size: "  
  14.                 + size);  
  15.     //1.保证容量  
  16.     ensureCapacity(size + 1); // Increments modCount!!  
  17.     //2.向右移动当前位于该位置的元素(如果有)以及所有后续元素(将其索引加 1)。   
  18.     System.arraycopy(elementData, index, elementData, index + 1, size  
  19.             - index);  
  20.     //3.将指定的元素插入此列表中的指定位置  
  21.     elementData[index] = element;  
  22.     size++;  
  23. }  
  24.   
  25. // 检查容量,minCapacity=size+1  
  26. public void ensureCapacity(int minCapacity) {  
  27.     modCount++;  
  28.     int oldCapacity = elementData.length;  
  29.     // 如果超过容量  
  30.     if (minCapacity > oldCapacity) {  
  31.         Object oldData[] = elementData;  
  32.         // 新容量=(老容量 * 3)/2 + 1  
  33.         // 如果老容量为10,则新容量为16  
  34.         int newCapacity = (oldCapacity * 3) / 2 + 1;  
  35.         //newCapacity < minCapacity会产生这样的情况?????  
  36.         if (newCapacity < minCapacity)  
  37.             newCapacity = minCapacity;  
  38.         //复制原数组数据到大小为newCapacity的数组中  
  39.         elementData = Arrays.copyOf(elementData, newCapacity);  
  40.     }  
  41. }  
  42.   
  43. //替换数据  
  44. public E set(int index, E element) {  
  45.     RangeCheck(index);  
  46.     //保存index处旧值  
  47.     E oldValue = (E) elementData[index];  
  48.     //赋新值  
  49.     elementData[index] = element;  
  50.     return oldValue;  
  51. }  
  52. //下标志检查  
  53. private void RangeCheck(int index) {  
  54.     if (index >= size)  
  55.         throw new IndexOutOfBoundsException("Index: " + index + ", Size: "  
  56.                 + size);  
  57. }  

 

四.取数据

Java代码  收藏代码
  1. public E get(int index) {  
  2.     RangeCheck(index);  
  3.     return (E) elementData[index];  
  4. }  
  5.   
  6. // 返回第一次出现o的下标,用equals比较  
  7. // 如果不存在o,返回-1  
  8. public int indexOf(Object o) {  
  9.     if (o == null) {  
  10.         for (int i = 0; i < size; i++)  
  11.             if (elementData[i] == null)  
  12.                 return i;  
  13.     } else {  
  14.         for (int i = 0; i < size; i++)  
  15.             if (o.equals(elementData[i]))  
  16.                 return i;  
  17.     }  
  18.     return -1;  
  19. }  
  20.   
  21. // 想想为什么不这么实现  
  22. // 上面的实现方式比较次数2+n,下面的比较次数2*n  
  23. public int indexOf(Object o) {  
  24.     for (int i = 0; i < size; i++) {  
  25.         if (o == null) {  
  26.             if (elementData[i] == null)  
  27.                 return i;  
  28.         } else {  
  29.             if (o.equals(elementData[i]))  
  30.                 return i;  
  31.         }  
  32.     }  
  33.     return -1;  
  34. }  
  35.   
  36. // 从size-1往0遍历  
  37. public int lastIndexOf(Object o) {  
  38.     if (o == null) {  
  39.         for (int i = size - 1; i >= 0; i--)  
  40.             if (elementData[i] == null)  
  41.                 return i;  
  42.     } else {  
  43.         for (int i = size - 1; i >= 0; i--)  
  44.             if (o.equals(elementData[i]))  
  45.                 return i;  
  46.     }  
  47.     return -1;  
  48. }  

 

五.删数据

Java代码  收藏代码
  1. //移除index处的元素是List接口里新加的方法  
  2. //同Map一样,在插入元素的操作中会扩容,删除元素并不去减容  
  3. public E remove(int index) {  
  4.     RangeCheck(index);  
  5.   
  6.     modCount++;  
  7.     E oldValue = (E) elementData[index];  
  8.     //需要移动的元素个数  
  9.     int numMoved = size - index - 1;  
  10.     if (numMoved > 0)  
  11.         //数组内(间)元素移动,五个参数依次为  
  12.         //src - 源数组。  
  13.         //srcPos - 源数组中的起始位置。  
  14.         //dest - 目标数组。  
  15.         //destPos - 目标数据中的起始位置。  
  16.         //length - 要复制的数组元素的数量。  
  17.         System.arraycopy(elementData, index + 1, elementData, index,  
  18.                 numMoved);  
  19.     //让GC回收因移动空出的数组最后一位  
  20.     elementData[--size] = null;   
  21.   
  22.     return oldValue;  
  23. }  
  24.   
  25. //remove某个元素是Collection接口里的方法  
  26. //同Map一样,在插入元素的操作中会扩容,删除元素并不去减容  
  27. //remove(int index)和remove(Object o)一次只会移除一个元素  
  28. public boolean remove(Object o) {  
  29.     if (o == null) {  
  30.         for (int index = 0; index < size; index++)  
  31.             if (elementData[index] == null) {  
  32.                 fastRemove(index);  
  33.                 return true;  
  34.             }  
  35.     } else {  
  36.         for (int index = 0; index < size; index++)  
  37.             if (o.equals(elementData[index])) {  
  38.                 fastRemove(index);  
  39.                 return true;  
  40.             }  
  41.     }  
  42.     return false;  
  43. }  
  44.   
  45. //把index后的元素移往前移一位  
  46. private void fastRemove(int index) {  
  47.     modCount++;  
  48.     int numMoved = size - index - 1;  
  49.     if (numMoved > 0)  
  50.         System.arraycopy(elementData, index + 1, elementData, index,  
  51.                 numMoved);  
  52.     //让GC回收因移动空出的数组最后一位  
  53.     elementData[--size] = null;   
  54. }  

 

六.List与Array

Java代码  收藏代码
  1. //ArrayList转换成数组  
  2. //将ArrayList内部的数组0到size-1位返回即可  
  3. public Object[] toArray() {  
  4.     return Arrays.copyOf(elementData, size);  
  5. }  
  6.   
  7. //ArrayList转换成指定数组a  
  8. public <T> T[] toArray(T[] a) {  
  9.     if (a.length < size)  
  10.         // Make a new array of a's runtime type, but my contents:  
  11.         return (T[]) Arrays.copyOf(elementData, size, a.getClass());  
  12.     System.arraycopy(elementData, 0, a, 0, size);  
  13.     if (a.length > size)  
  14.         a[size] = null;  
  15.     return a;  
  16. }  

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics