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(); } } }
阅读全文
0 0
- java源码学习-----ArrayList
- java ArrayList源码学习
- JAVA源码学习-ArrayList
- 源码学习之ArrayList
- java源码学习----ArrayList
- ArrayList源码学习
- ArrayList源码学习笔记
- ArrayList源码学习
- ArrayList源码学习
- ArrayList源码学习
- ArrayList源码学习
- JDK源码学习之ArrayList
- 集合学习--ArrayList 源码初探
- ArrayList<E>源码学习笔记
- ArrayList部分源码学习笔记
- ArrayList源码解析与学习
- jdk源码学习笔记---ArrayList
- ArrayList源码学习(1.1)
- 《JavaScript语言精粹》笔记(2)--对象
- Struts2:登录验证码(随机字符串)的实现
- cookie&session
- 内联函数总结
- RecyclerView
- ArrayList源码学习
- SQL模糊查询排序问题
- 关于人工智能的一些介绍与看法
- keepalived+nginx的配置
- MySQL优化系列(七)--视图应用详解
- Vuforia的学习(五)ImageTarget的使用
- 51NOD 1316 回文矩阵 【枚举】
- uva 401
- 1999: [Noip2007]Core树网的核