容器-数组-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];   //直接获取数组的索引位
    }

posted on 2012-02-20 14:28 陈睿 阅读(1097) 评论(0)  编辑  收藏 所属分类: 高级


只有注册用户登录后才能发表评论。


网站导航:
 

导航

<2012年2月>
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910

统计

常用链接

留言簿

随笔分类

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜