加入收藏 | 设为首页
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

ArrayList相关方法的实现逻辑

Posted on 2015-01-21 14:04  墨香一点足以  阅读(277)  评论(0)    收藏  举报

记得曾经遇到过的一道面试题是这样的:说明java.util.ArrayList以下方法的实现逻辑。1.boolean add(E e);2.void add(int index,E element);3.void clear();4.E get(int index);5.int indexOf(Object o);6.E remove(ini index);7.boolean remove(Objecto);8.int size().

  ArrayList是List接口的大小可变数组的实现,实现了所有可选列表的操作,并允许包括null在内的所有元素。除了实现List接口外,此类还提供些方法来操作内部用来存储列表的数组的大小。

  size、isEmpty、get、set、iterator和listIterator操作都以固定时间运行。add操作以分摊的固定时间运行,即添加n个元素需要O(n)时间,其他所有操作都以线性时间运行。与LinkedList实现的常数因子相比,此实现的常数因子较低。

  每个ArrayList实例都有一个容量,至少等于列表的大小,添加元素列表自动增长。在添加大量元素前,应用程序可使用ensureCapacity操作来增加ArrayList实例的容量,这可以减少递增式再分配的数量。

  注意,此实现不是同步的。如果多个线程同时访问一个ArrayList实例,而其中至少一个线程从结构上修改列表(指任何添加或删除一个或多个元素的操作,或显式调整底层数组的大小,仅设置元素的值不算),那它必须保持外部同步。

ArrayList实现:

1.实现List接口,底层使用数组保存所有元素:

private transient Object[] elementData;

从类 java.util.

AbstractList

继承的字段protected transient int modCount:已从结构上修改 此列表的次数。从结构上修改是指更改列表的大小,或者打乱列表,从而使正在进行的迭代产生错误的结果。 此字段由 iteratorlistIterator 方法返回的迭代器和列表迭代器实现使用。2.构造方法:有三种构造方法1).构造一个默认初始容量为10的空列表:

public ArrayList(){
    this(10);
}

2).构造一个具有指定初始容量的空列表:

public ArrayLst(int initialCapacity){
    super();
    if(initialCapacity<0){
        throw new IllegalArguementException("Illegal Capacity:+initialCapacity");
    this.elementData=new Object[initialCapacity];
}

3)构造一个包含指定collection的元素,按该collection的迭代器返回它们的顺序排列:

public ArrayList(Collection<? extends E> c){
    elementData=c.toArray();
    size=elementData.length;
    //c.toArray() might (incorrectly) not return Object[] (see 6260652)
    if(elementData.getClass()!=Object[].class)
        elementData=Arrays.copyOf(elementData,size,Object[].class);
}

3.方法实现逻辑

1).boolean add(E e):将指定元素添加到此列表的尾部。12

public boolean add(E e){
    ensureCapacity(size+1);//Increments modCount!
    elementData[size++]=e;
    return true;
}

2).void add(int index,E element):将指定的元素插入此列表中的指定位置。

public void add(int index,E element){
    if(index>size || index<0)
        throw new IndexOutBundException("Index:"+index+",Size:"+size);
    ensureCapacity(size+1);//Increments modCount
    System.arraycopy(elementData,index,elementData,index+1,size-index);
    elementData[index]=element;
    size++;
}

3).void clear():移除此列表中的所有元素。

public void clear(){
    modCount++;
    for(int i=0;i<size;i++)
        elementData[i]=null;
    size=0;
}

4).E get(int index):返回此列表中指定位置上的元素。

public E get(int index){
    RangeCheck(index);
    return (E) elementData[index];
}

5).int indexOf(Object o):返回列表中首次出现的指定元素的索引,否则返回-1。

public int indexOf(Object o){
    if(o==null){
        for(int i=0;i<size;i++)
            if(elementData[i]==null) return i;
    }else{
        for(int i=0;i<size;i++)
            if(o.equal(elementData[i])) return i;
    }
    return -1;
}

6).E remove(int index):移除此列表中指定位置上的元素。

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,numMoved);
    elementData[--size]=null;//Let gc do its work
    return oldValue;
}

7).boolean remove(Object o):移除此列表中首次出现的指定元素(若存在)。

public boolean remove(Object o){
    if(o==null){
        for(int index=0;index<size;index++)
            if(elementData[index]==null)
                fastRemove(index);
                return true;
            }
    }else{
        for(int index=0;index<size;index++){
            if(o.equals(elementData[index])){
                fastRemove(index);
                return true;
            }
    }
    return false;
}

private void fastRemove(int index){
    modCount++;
    int numMoved=size-index-1;
    if(numMoved>0)
        System.arraycopy(elementData,index+1,elementData,index,numMoved);
    elementData[--size]=null;
}

8).int size():返回列表中的元素数。

public int size(){
    return size;
}

9).E set(int index,E element):用指定元素替代此列表中指定位置上的元素。

public E set(int index,E element){
    RangeCheck(index);
    E oldValue=(E)elementData[index];
    elementData[index]=element;
    return oldValue;
}

10).void ensureCapacity(int minCapacity):如必要,增加此ArrayList实例的容量,以确保它至少能够容纳最小容量参数所指定的元素数。

public void ensureCapacity(int minCapacity){
    modCount++;
    int oldCapacity=elementData.length;
    if(minCapacity>oldCapacity){
        Object oldData[]=elementData;
        int newCapacity=(oldCapacity*3)/2+1;
        if(newCapacity<minCpacity)
                  newCapacity=minCapacity;//minCapacity is usually close to size,so this is a win
        elementData=Arrays.copyOf(elementData,newCapacity);
    }
}

11).boolean contains(Object o):如此列表中包含指定的元素,则返回true。

public boolean contains(Object o){
    return indexOf(o)>=0;
}

12).Object clone():返回此ArrayList实例的浅表副本

public Object clone(){
    try{
        ArrayList<E> v=(ArrayList<E>)super.clone();
        v.elementData=Arrays.copyOf(elementData,size);
        v.modCount=0;
        return v;
    }catch(CloneNotSupportedException e){
        //this shouldn't happen,since we are Cloneable
        throw new InternalError();
    }
}