记得曾经遇到过的一道面试题是这样的:说明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:已从结构上修改 此列表的次数。从结构上修改是指更改列表的大小,或者打乱列表,从而使正在进行的迭代产生错误的结果。 此字段由 iterator 和 listIterator 方法返回的迭代器和列表迭代器实现使用。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(); } }
浙公网安备 33010602011771号