• java1.7集合源码阅读:ArrayList


    ArrayList是jdk1.2开始新增的List实现,首先看看类定义:

    1 public class ArrayList<E> extends AbstractList<E>
    2         implements List<E>, RandomAccess, Cloneable, java.io.Serializable
    3 {
    4   ...........  
    5 }
    ArrayList实现List接口,上层接口是Collection,顶级接口是Iterable,同时还实现了Cloneable、Serializable、RandomAccess接口,以支持克隆、序列化、快速访问。
    ArrayList初始容量为10,同时也支持初始化指定初始容量以及使用另一个集合作为初始参数,真正存储数据的是:
    1     private transient Object[] elementData;
    2     ......
    3   public ArrayList(int initialCapacity) {
    4         super();
    5         if (initialCapacity < 0)
    6             throw new IllegalArgumentException("Illegal Capacity: "+
    7                                                initialCapacity);
    8         this.elementData = new Object[initialCapacity];
    9     }
    ArrayList内部以数组结构存储数据,相关add、get等方法基本上都是对数组的相关操作,但在增删操作的时候会进行边界检查,增加操作时还要验证容量,当容量不够时会进行扩容.
    验证边界:
     1   private void rangeCheck(int index) {
     2         if (index >= size)
     3             throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
     4     }
     5 
     6     /**
     7      * A version of rangeCheck used by add and addAll.
     8      */
     9     private void rangeCheckForAdd(int index) {
    10         if (index > size || index < 0)
    11             throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    12     }

    容量验证及扩容:

     1   /**
     2      * Increases the capacity of this <tt>ArrayList</tt> instance, if
     3      * necessary, to ensure that it can hold at least the number of elements
     4      * specified by the minimum capacity argument.
     5      *
     6      * @param   minCapacity   the desired minimum capacity
     7      */
     8     public void ensureCapacity(int minCapacity) {
     9         int minExpand = (elementData != EMPTY_ELEMENTDATA)
    10             // any size if real element table
    11             ? 0
    12             // larger than default for empty table. It's already supposed to be
    13             // at default size.
    14             : DEFAULT_CAPACITY;
    15 
    16         if (minCapacity > minExpand) {
    17             ensureExplicitCapacity(minCapacity);
    18         }
    19     }
    20 
    21     private void ensureCapacityInternal(int minCapacity) {
    22         if (elementData == EMPTY_ELEMENTDATA) {
    23             minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    24         }
    25 
    26         ensureExplicitCapacity(minCapacity);
    27     }
    28 
    29     private void ensureExplicitCapacity(int minCapacity) {
    30         modCount++;
    31 
    32         // overflow-conscious code
    33         if (minCapacity - elementData.length > 0)
    34             grow(minCapacity);
    35     }
    36     private void grow(int minCapacity) {
    37         // overflow-conscious code
    38         int oldCapacity = elementData.length;
    39         int newCapacity = oldCapacity + (oldCapacity >> 1);
    40         if (newCapacity - minCapacity < 0)
    41             newCapacity = minCapacity;
    42         if (newCapacity - MAX_ARRAY_SIZE > 0)
    43             newCapacity = hugeCapacity(minCapacity);
    44         // minCapacity is usually close to size, so this is a win:
    45         elementData = Arrays.copyOf(elementData, newCapacity);
    46     }

    扩容时,为原容量的1.5倍。

    ArrayList对Iterator接口的实现:

     1   /**
     2      * An optimized version of AbstractList.Itr
     3      */
     4     private class Itr implements Iterator<E> {
     5         int cursor;       // index of next element to return
     6         int lastRet = -1; // index of last element returned; -1 if no such
     7         int expectedModCount = modCount;
     8 
     9         public boolean hasNext() {
    10             return cursor != size;
    11         }
    12 
    13         @SuppressWarnings("unchecked")
    14         public E next() {
    15             checkForComodification();
    16             int i = cursor;
    17             if (i >= size)
    18                 throw new NoSuchElementException();
    19             Object[] elementData = ArrayList.this.elementData;
    20             if (i >= elementData.length)
    21                 throw new ConcurrentModificationException();
    22             cursor = i + 1;
    23             return (E) elementData[lastRet = i];
    24         }
    25 
    26         public void remove() {
    27             if (lastRet < 0)
    28                 throw new IllegalStateException();
    29             checkForComodification();
    30 
    31             try {
    32                 ArrayList.this.remove(lastRet);
    33                 cursor = lastRet;
    34                 lastRet = -1;
    35                 expectedModCount = modCount;
    36             } catch (IndexOutOfBoundsException ex) {
    37                 throw new ConcurrentModificationException();
    38             }
    39         }
    40 
    41         final void checkForComodification() {
    42             if (modCount != expectedModCount)
    43                 throw new ConcurrentModificationException();
    44         }
    45     }

    当对ArrayList进行for循环时,如有对集合进行增删改操作时,会报产生ConcurrentModificationException异常。

    特别注意:ArrayList不是线程安全的,存在线程安全问题可使用Vector。

     
     
  • 相关阅读:
    OAuth2.0认证和授权原理
    APNs详细使用步骤
    解决IDEA因分配内存而引起的卡顿
    JAVA 第二周学习总结
    JAVA 第一周学习总结
    Mac OS 上配置java开发环境
    【DP】【单调队列】洛谷 P2216 [HAOI2007]理想的正方形 题解
    【DP】【构造】NOIp模拟题 演讲 题解
    【2-SAT】【并查集】NOIp模拟题 植树方案 题解
    【字符串】【hash】【倍增】洛谷 P3502 [POI2010]CHO-Hamsters 题解
  • 原文地址:https://www.cnblogs.com/jessezeng/p/5023952.html
Copyright © 2020-2023  润新知