容器-数组-ArrayList

容器-数组-ArrayList

1. ArrayList概要:
  • 默认长度为10
                  public ArrayList() {
                 this ( 10 );
                 }
  • 底层采用数组存储private transient Object[] elementData;
        transient表示数组elementData不需要通过serialization序列化传输
  • 线程不安全,在多线程场景会出现问题,可以考虑使用Vector或者Collections.synchronizedList同步该容器
  • 查询效率比较高,比较适用于查询
  • 扩容的长度为初始长度的一半,建议初始化的时候设置已知的长度,免得容器自己去扩容,浪费空间以及效率

2. ArrayList代码详解:

  • 增加元素
  public boolean add(E e) {
    ensureCapacity(size  +   1 );   //  Increments modCount!!
    elementData[size ++ =  e;
    
return   true ;
    }
首先检查数组是否已满,如果满了就开始扩容,扩容后的长度为原长度的1.5倍。
/**
     * Increases the capacity of this <tt>ArrayList</tt> instance, if
     * necessary, to ensure that it can hold at least the number of elements
     * specified by the minimum capacity argument.
     *
     * 
@param    minCapacity   the desired minimum capacity
     
*/
    
public   void  ensureCapacity( int  minCapacity) {
    modCount
++ ; //modCount表示数组的操作计数,用于iterator的时候与
expectedMod
Count比较,防止迭代操作对add,remove等操作影响迭代操作
   int  oldCapacity  =  elementData.length;
    
if  (minCapacity  >  oldCapacity) {         //新插入元素后的长度大于老的长度,数组开始扩容
        Object oldData[] 
=  elementData;
        
int  newCapacity  =  (oldCapacity  *   3 ) / 2   +   1 ; //新空间为原长度的1.5倍,等于是扩容了50%
            
if  (newCapacity  <  minCapacity)
        newCapacity 
=  minCapacity;
            
//  minCapacity is usually close to size, so this is a win:
            elementData  =  Arrays.copyOf(elementData, newCapacity); //把之前的元素拷贝到新的数组    }
    }

  • 删除元素:

/**
     * Removes the element at the specified position in this list.
     * Shifts any subsequent elements to the left (subtracts one from their
     * indices).
     *
     * 
@param  index the index of the element to be removed
     * 
@return  the element that was removed from the list
     * 
@throws  IndexOutOfBoundsException { @inheritDoc }
     
*/
    
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,//复制原数组制定index+1到length-1的元素到elementData的index的索引位
                 numMoved);
    elementData[
-- size]  =   null //  Let gc do its work//最后一位设置为null

    
return  oldValue;
    }

  /**
     * Checks if the given index is in range.  If not, throws an appropriate
     * runtime exception.  This method does *not* check if the index is
     * negative: It is always used immediately prior to an array access,
     * which throws an ArrayIndexOutOfBoundsException if index is negative.
     
*/
    
private   void  RangeCheck( int  index) {
    
if  (index  >=  size)
        
throw   new  IndexOutOfBoundsException(
        
" Index:  " + index + " , Size:  " + size);
    }

  • 获取元素:
  /**
     * Returns the element at the specified position in this list.
     *
     * 
@param   index index of the element to return
     * 
@return  the element at the specified position in this list
     * 
@throws  IndexOutOfBoundsException { @inheritDoc }
     
*/
    
public  E get( int  index) {
    RangeCheck(index);

    
return  (E) elementData[index];   //直接获取数组的索引位
    }

你可能感兴趣的:(容器-数组-ArrayList)