ArrayList源码学习

来源:互联网 发布:武汉大学网络教学平台 编辑:程序博客网 时间:2024/05/30 05:42

ArrayList:一个由数组实现的集合对象,默认容量为10。

特点:1、随机查找快(因为数组是连续的内存空间可以使用索引直接定位数组内的元素)。

2、随机插入慢(因为会移动数组)。


方法:add():

 public boolean add(E e) {        ensureCapacityInternal(size + 1);  // 根据需要判断是否需要扩容        elementData[size++] = e;// 添加元素到数组中        return true;    }
grow():扩容时先判断当前数组size的2倍是否满足所需最小size,如果不满足则直接设size为所需的最小size

 private void grow(int minCapacity) {        // overflow-conscious code        int oldCapacity = elementData.length;        int newCapacity = oldCapacity + (oldCapacity >> 1);        if (newCapacity - minCapacity < 0)            newCapacity = minCapacity;        if (newCapacity - MAX_ARRAY_SIZE > 0)            newCapacity = hugeCapacity(minCapacity);// 如果所需最小容量大于MAX_ARRAY_SIZE则设置最大容量为Integer.MAX_VALUE        // minCapacity is usually close to size, so this is a win:        elementData = Arrays.copyOf(elementData, newCapacity);// 把原数组元素复制到新数组中    }


重载的构造方法:

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) //保证ArrayList内部维护的数组类型是Object[]            elementData = Arrays.copyOf(elementData, size, Object[].class);    }

indexOf()返回元素在数组的索引:

public int indexOf(Object o) {        if (o == null) {//对Null元素查找            for (int i = 0; i < size; i++)                if (elementData[i]==null)                    return i;        } else {            for (int i = 0; i < size; i++)                if (o.equals(elementData[i]))通过equals来判断是否相等                    return i;        }        return -1;    }

add(E e):

public boolean add(E e) {        ensureCapacityInternal(size + 1);  // 检查当前数组长度是否足够        elementData[size++] = e;        return true;    }

add(int index, E e):

public void add(int index, E element) {        rangeCheckForAdd(index);        ensureCapacityInternal(size + 1);  // modCount变量++,并且判断你数组是否需要扩容        System.arraycopy(elementData, index, elementData, index + 1,                         size - index);//把数组index位置的元素向后移动,挪出空间        elementData[index] = element;// 在数组的index位置插入元素        size++;    }


set():

public E set(int index, E element) {        rangeCheck(index);//检查索引是否越界        E oldValue = elementData(index);        elementData[index] = element;        return oldValue;    }
remove():
   public E remove(int index) {        rangeCheck(index);// 检查传进来的参数index是否越界        modCount++; //记录修改        E oldValue = elementData(index); //取得旧值        int numMoved = size - index - 1;// 计算出被删除的元素的后面有几个元素需要向前移动        if (numMoved > 0)// 删除的不是最后一个元素,需要移动数组中的元素            System.arraycopy(elementData, index+1, elementData, index,                             numMoved);// 通过复制数组的方式把后面的元素向前移动        elementData[--size] = null; // 把数组末尾的元素置null,使得GC可以回收.(因为size-1处的元素就是原来size处的元素)        return oldValue;    }


subList(int fromIndex, int toIndex):

public List<E> subList(int fromIndex, int toIndex) {        subListRangeCheck(fromIndex, toIndex, size);        return new SubList(this, 0, fromIndex, toIndex);返回的是一个内部类,内部类的操作都是对原容器中的数组进行操作    }


Iterator:

private class Itr implements Iterator<E> {一个实现了Iterator接口的私有内部类        int cursor;       // 下一个元素的索引        int lastRet = -1; // 最后一次操作的元素的索引(当前操作的元素); -1 if no such        int expectedModCount = modCount;  //修改的次数,用于判断是否有并发修改        public boolean hasNext() {            return cursor != size;        }        @SuppressWarnings("unchecked")        public E next() {            checkForComodification();//获取下一个元素前检查当前集合是否被修改            int i = cursor;            if (i >= size)                throw new NoSuchElementException();            Object[] elementData = ArrayList.this.elementData;//获取到集合底层保存数据的数组对象            if (i >= elementData.length)//                 throw new ConcurrentModificationException();            cursor = i + 1;            return (E) elementData[lastRet = i];        }        public void remove() {            if (lastRet < 0)                throw new IllegalStateException();            checkForComodification();            try {                ArrayList.this.remove(lastRet);// 从集合中移除当前元素                cursor = lastRet; //修复指向下一个元素的指针(),因为删除当前元素后,当前元素后面的元素会向前移动                lastRet = -1;                expectedModCount = modCount;// 同步修改次数            } catch (IndexOutOfBoundsException ex) {                throw new ConcurrentModificationException();            }        }
// 检查当前集合是否被修改(并发、或者在iterator迭代时直接调用了容器的修改方法)
final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }


ListIterator:在迭代过程中可以前进后退的iterator

private class ListItr extends Itr implements ListIterator<E> {        ListItr(int index) {            super();            cursor = index;        }        public boolean hasPrevious() {            return cursor != 0;        }        public int nextIndex() {            return cursor;        }        public int previousIndex() {            return cursor - 1;        }        @SuppressWarnings("unchecked")        public E previous() {            checkForComodification();            int i = cursor - 1; // 指针前移一位            if (i < 0)                throw new NoSuchElementException();            Object[] elementData = ArrayList.this.elementData;            if (i >= elementData.length)                throw new ConcurrentModificationException();            cursor = i;            return (E) elementData[lastRet = i]; //返回前一个元素        }        public void set(E e) {            if (lastRet < 0)                throw new IllegalStateException();            checkForComodification();            try {                ArrayList.this.set(lastRet, e);// 调用容器的set方法在当前索引设置元素            } catch (IndexOutOfBoundsException ex) {                throw new ConcurrentModificationException();            }        }        public void add(E e) {            checkForComodification();            try {                int i = cursor;                ArrayList.this.add(i, e);// 在指向下一个元素的指针指向的位置前边插入一个元素                cursor = i + 1; //修复指针位置,跳过刚插入的元素                lastRet = -1;                expectedModCount = modCount;            } catch (IndexOutOfBoundsException ex) {                throw new ConcurrentModificationException();            }        }    }







原创粉丝点击