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一样,只是这个循环从最后一个开始,向前循环。所以查找的是最后一个。
?
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() 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。
??? ??? ??? ???
????克隆被覆写
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 就算看完了。