首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

ArrayList源码懂得

2012-10-25 
ArrayList源码理解构造方法:????这个类中有一个Object[]的对象来存储数据,代码是:this.elementData new

ArrayList源码理解
构造方法:

????这个类中有一个Object[]的对象来存储数据,代码是:

this.elementData = new Object[initialCapacity];//存储对象的数组
?

??? initialCapacity默认是10,这个elementData定义的时候用transient定义,不知道什么意思。size为集合的长度int。默认没有给值,所以是0。
???构造方法:

public ArrayList(int initialCapacity) {        this.elementData = new Object[initialCapacity];}

??? 构造方法:

public ArrayList() {        this(10);}
?

??? 在构造方法中

public ArrayList(Collection<? extends E> c) {          //返回一个Object[]的副本对象(大部分是这样),长度会是内部变量的长度size,而不是这个Object[]的长度            elementData = c.toArray();            size = elementData.length;            //这里验证内部的值是否是Object[],然后依情况转成Object类型            if (elementData.getClass() != Object[].class)                 //这里复制出来的Onject[]值所占空间为size,内部变量的数目也是size                elementData = Arrays.copyOf(elementData, size, Object[].class);}

???? 在这个构造方法中会将c中的值转为Object[]类型,在c.toArray()中,一般会传出一个对象的副本,即利用copy传出elementData的数据。所以这里很有可能是复制了两次数据。

add方法

????返回的是否添加成功。注意,这里面竟然可以添加null值。

public boolean add(E e) {    //增加此 ArrayList 实例的容量,以确保它至少能够容纳最小容量参数所指定的元素数。    ensureCapacity(size + 1);     //复制后size+1    elementData[size++] = e;    return true; }

??? 类中的E泛型 不过都会当成Object处理??
? ? 上面的第一句代码:

public void ensureCapacity(int minCapacity) {                        //不知道这句是干什么的?????????????????????                        modCount++;                        //获取当前数组长度,而并不是内部拥有的变量size                        int oldCapacity = elementData.length;                        //如果总空间不够的话                        if (minCapacity > oldCapacity) {                                                           Object oldData[] = elementData;                            //开辟1.5倍+1的空间                            int newCapacity = (oldCapacity * 3)/2 + 1;                            //如果依然不够的话,直接开辟minCapacity的空间                        if (newCapacity < minCapacity)                                        newCapacity = minCapacity;                                //将数据复制到新的数组中                        elementData = Arrays.copyOf(elementData, newCapacity);         }} 

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

public void add(int index, E element) {           //这个就不说了,越界            if (index > size || index < 0)                   throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);          //容量保证          ensureCapacity(size+1);          //复制index后size-index长度的值到index+1的位置上,就是将index后面的内容向后移动一位,把index这个位置空出来         System.arraycopy(elementData, index, elementData, index + 1,size - index);        //赋值        elementData[index] = element;        //大小+1        size++;}

?

public boolean addAll(Collection<? extends E> c) {Object[] a = c.toArray();//a.length 相当于复制过来c的size。这里也是数组所占空间 int numNew = a.length;ensureCapacity(size + numNew); //将加入的a复制到size之后,注意这里都是数组的位置,System.arraycopy(a, 0, elementData, size, numNew);//更新sizesize += numNew;//这个很有特色,按照添加的长度来判断是否成功。很危险return numNew != 0;}
?
public boolean addAll(int index, Collection<? extends E> c) {if (index > size || index < 0)    throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);Object[] a = c.toArray();int numNew = a.length;ensureCapacity(size + numNew); int numMoved = size - index;//这里是判断是否需要系统,如果index 和size一样大的话就复制移动了。if (numMoved > 0)    System.arraycopy(elementData, index, elementData, index + numNew,numMoved);System.arraycopy(a, 0, elementData, index, numNew);size += numNew;return numNew != 0;}

?

get方法

?

public E get(int index) {//范围检查RangeCheck(index);//竟然会强转,不过想想也很正常。return (E) elementData[index];}//只是做了一个越界检查private void RangeCheck(int index) {if (index >= size)    throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);}

?

size方法

?

public int size() {        //直接返回size的值。return size;}

?

clear方法
public void clear() {//这里又不知道在干什么modCount++;//看来数组的空间不会改变,内部的变量都清空了。for (int i = 0; i < size; i++)//所有的值赋了空值。    elementData[i] = null;size = 0;}
remove方法 ??? ???

??? 返回删除对象

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; //返回return oldValue;}

?

??? 返回是否删除成功

public boolean remove(Object o) { //第一步直接把对象强转为Object类型了。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++)    //注意这里判断的删除只是equals相同就行,这个地方很有奇异,if (o.equals(elementData[index])) {    fastRemove(index);    //只会删除碰到的第一条相同对象    return true;}       }   //没找到会返回false。return false;}
?

?

?? 快速删除

private void fastRemove(int index) { //又是这个神秘的变量  modCount++;  //和上面的删除是一个人写的,一样。  int numMoved = size - index - 1;  if (numMoved > 0)      System.arraycopy(elementData, index+1, elementData, index, numMoved);  //size-1  elementData[--size] = null;}

?

?? ArrayList里面的removeAll是调用的下面class的方法。

??AbstractCollection.class

 public boolean removeAll(Collection<?> c) {boolean modified = false;Iterator<?> e = iterator();while (e.hasNext()) {//包含的方法下面会看到。    if (c.contains(e.next())) {e.remove();//这里是删除所有的modified = true;    }}return modified;  } public boolean retainAll(Collection<?> c) {boolean modified = false;Iterator<E> e = iterator();while (e.hasNext()) {    if (!c.contains(e.next())) { //   不包含的关系,就是几乎会删除掉原对象中所有的值e.remove();modified = true;    }}return modified;  }

?

indexOf方法 ????

?

public int indexOf(Object o) {if (o == null) {    for (int i = 0; i < size; i++)    //在size之前找到空,会返回,超过size后没用if (elementData[i]==null)    return i;} else {//依然只是比较equals方法。    for (int i = 0; i < size; i++)if (o.equals(elementData[i]))//只返回查找的第一个。    return i;}//找不到返回 int -1return -1;}
?

?

lastIndexOf方法

??? lastIndexOf(Object o)
???返回此列表中最后一次出现的指定元素的索引,或如果此列表不包含索引,则返回 -1。
???和index一样,只是这个循环从最后一个开始,向前循环。所以查找的是最后一个。

toArray方法

?

public Object[] toArray() {//返回一个数组,数组空间和变量同样大小的。return Arrays.copyOf(elementData, size);}

??? 未定义泛型的时候Object[] 不能强转成 E[] ,

trimToSize方法

??? 将此 ArrayList 实例的容量调整为列表的当前大小

public void trimToSize() {//未知modCount++;int oldCapacity = elementData.length;if (size < oldCapacity) {            elementData = Arrays.copyOf(elementData, size);}}

?

set方法

????E set(int index,E element)
????就是将对应未知的变量换成新的,将旧的值返回,当然先是对越界做过滤。

isEmpty方法

?

isEmpty()  public boolean isEmpty() {return size == 0;}

??? 代码更容易懂。

contains方法

???如果此列表中包含指定的元素,则返回 true。

public boolean contains(Object o) {return indexOf(o) >= 0;}public boolean containsAll(Collection<?> c) {Iterator<?> e = c.iterator();while (e.hasNext())  if (!contains(e.next()))return false;return true;} 

?? 这里是不讲究顺序,只要c中的变量都有就行。例如:a={1,3,2,4},b={1,3,3} 这里,a包含b。

??? ??? ??? ???

clone方法

????克隆被覆写

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();}}
?

??? ???
?好了ArrayList 就算看完了。

热点排行