ArrayList源码解析
来源:互联网 发布:org.apache.tools.ant 编辑:程序博客网 时间:2024/05/21 03:20
一、概述
ArrayList类提供了可调整大小的数组(动态数组),并实现了List接口。ArrayList类实现了所有可选的列表操作,并且允许所有元素,包括空值null。它提供了一些方法来操作内部用来存储列表的数组的大小。相较于LinkedList实现的常数因子较低。
二、功能
1、ArrayList 继承AbstractList,实现了List。它是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。
2、提供了随机访问功能。
3、可以通过元素的序号快速获取元素对象。
4、支持序列化,能通过序列化去传输。
5、能被克隆。
三、特点
1、随机访问速度快,插入、删除、移动性能较差。
2、支持null元素。
3、有序。
4、元素可以重复。
5、线程不安全。
四、为什么说ArrayList是线程不安全的?
1、线程安全
线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。
2、线程不安全
线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据。
3、ArrayList是线程不安全的
private void ensureCapacityInternal(int minCapacity) { if (elementData == EMPTY_ELEMENTDATA) { //若elementData=={},则取minCapacity为默认容量和参数minCapacity之间的最大值 minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); }
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! //确定ArrayList的容量大小 elementData[size++] = e; //添加e到ArrayList中,然后size自增 1 return true; }
五、源码解析
ArrayList继承AbstractList,实现List、RandomAccess、Cloneable、java.io.Serializable接口。
AbstractList提供了List接口的默认实现。 List接口定义了列表必须实现的方法。RandomAccess是一个标记接口,接口内没有定义任何内容。实现Cloneable接口的类,可以调用Object.clone方法返回该对象的浅拷贝。通过实现 java.io.Serializable 接口以启用其序列化功能,序列化接口没有方法或字段,仅用于标识可序列化的语义。
//ArrayList<E>说明支持泛型public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { private static final long serialVersionUID = 8683452581122892189L; //序列号 private static final int DEFAULT_CAPACITY = 10; //默认初始化容量 private static final Object[] EMPTY_ELEMENTDATA = {}; //空数组 private transient Object[] elementData; //存储ArrayList内的元素;transient表示一个域不是该对象串行化的一部分,当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中 private int size; //ArrayList的大小(包含的元素数量)ArrayList构造方法(initialCapacity初始化elementData数组的大小)
public ArrayList(int initialCapacity) { //initialCapacity为初始容量 super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);//当初始容量非法时(小于0)抛出异常 this.elementData = new Object[initialCapacity]; }
ArrayList无参构造方法
public ArrayList() { super(); this.elementData = EMPTY_ELEMENTDATA; //创建一个空的ArrayList,此时其数组缓冲区elementData={},默认elementData初始容量为10 }
ArrayList构造方法,将提供的集合转成数组返回给elementData
public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); //返回包含c所有元素的数组 size = elementData.length; //将转换后的Object[]长度赋值给当前ArrayList的size // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) //若c.toArray()返回的数组类型不是Object[],则利用 Arrays.copyOf()来构造一个大小为size的Object[]数组 elementData = Arrays.copyOf(elementData, size, Object[].class); //复制指定数组 }
将当前容量值设为当前实际元素大小
public void trimToSize() { modCount++; if (size < elementData.length) { //当实际大小<数组缓冲区大小 elementData = Arrays.copyOf(elementData, size); //调整数组缓冲区 elementData,变为实际存储大小 } }
将集合的capacit增加minCapacity
public void ensureCapacity(int minCapacity) { //minCapacity为指定的最小容量 int minExpand = (elementData != EMPTY_ELEMENTDATA) //最小扩充容量,默认为10 // any size if real element table ? 0 // larger than default for empty table. It's already supposed to be // at default size. : DEFAULT_CAPACITY; if (minCapacity > minExpand) { //若用户指定的最小容量>最小扩充容量,则以用户指定的为准,否则还是10 ensureExplicitCapacity(minCapacity); } }
明确 ArrarList 的容量
private void ensureCapacityInternal(int minCapacity) { if (elementData == EMPTY_ELEMENTDATA) { //若elementData=={},则取minCapacity为默认容量和参数minCapacity之间的最大值 minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); }
明确ArrayList的容量,用于内部优化,保证空间资源不被浪费
private void ensureExplicitCapacity(int minCapacity) { modCount++; // 将"修改统计数"+1,该变量主要是用来实现fail-fast机制的 // overflow-conscious code if (minCapacity - elementData.length > 0) //确保指定的最小容量>数组缓冲区当前的长度,防止溢出代码 grow(minCapacity); }
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; //数组缓冲区最大存储容量
获取该 list 所实际存储的元素个数
public int size() { return size; }
判断list是否为空
public boolean isEmpty() { return size == 0; }
判断该 ArrayList是否包含Object类型对象
public boolean contains(Object o) { return indexOf(o) >= 0; }
顺序查找,返回元素的最低索引值
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.equals(elementData[i])) return i; } return -1; }
反向查找,返回元素的最高索引值
public int lastIndexOf(Object o) { if (o == null) { for (int i = size-1; i >= 0; i--) //逆序查找 if (elementData[i]==null) return i; } else { for (int i = size-1; i >= 0; i--) if (o.equals(elementData[i])) return i; } return -1; }
深度复制:对拷贝出来的ArrayList对象的操作,不会影响原来的ArrayList
Object 的clone()方法会复制本对象及其内所有基本类型成员和 String 类型成员,但不会复制对象成员、引用对象
public Object clone() { try { @SuppressWarnings("unchecked") 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的Object数组
对返回的该数组进行操作,不会影响该 ArrayList
public Object[] toArray() { return Arrays.copyOf(elementData, size); }
返回 ArrayList 元素组成的数组
@SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { //a为需要存储 list 中元素的数组 if (a.length < size) //若数组a的大小<ArrayList的长度,则将ArrayList全部拷贝到T[]中 // Make a new array of a's runtime type, but my contents: return (T[]) Arrays.copyOf(elementData, size, a.getClass()); System.arraycopy(elementData, 0, a, 0, size); if (a.length > size) //若数组a的大小>ArrayList的长度,则将ArrayList的全部元素拷贝到数组a中 a[size] = null; return a; }
返回在索引为 index 的元素
@SuppressWarnings("unchecked") E elementData(int index) { return (E) elementData[index]; }
获取指定位置的元素:从0开始计数
public E get(int index) { rangeCheck(index); return elementData(index); }
设置index位置元素的值
public E set(int index, E element) { rangeCheck(index); //设置 index 位置元素的值 E oldValue = elementData(index); elementData[index] = element; return oldValue; }
向elementData中添加元素
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! //确定ArrayList的容量大小 elementData[size++] = e; //添加e到ArrayList中,然后size自增 1 return true; }
在指定位置插入新元素,原先在index位置的值往后移动一位
public void add(int index, E element) { rangeCheckForAdd(index); ensureCapacityInternal(size + 1); // Increments modCount!! System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; }
移除指定索引位置的元素:index之后的所有元素依次左移一位
public E remove(int index) { rangeCheck(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; // clear to let GC do its work //将最后一个元素置空 return oldValue; }
删除ArrayList中的指定元素,只会删除一个
public boolean remove(Object o) { if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { //判断是否存储了null fastRemove(index); return true; } } else { for (int index = 0; index < size; index++) //遍历ArrayList找到“元素o”,则删除,并返回true if (o.equals(elementData[index])) { fastRemove(index); return true; } } return false; }
快速删除第index个元素
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; // clear to let GC do its work }
清空所有存储元素,它会将数组缓冲区所以元素置为null
public void clear() { modCount++; // clear to let GC do its work for (int i = 0; i < size; i++) elementData[i] = null; size = 0; }
将一个集合的所有元素顺序添加到list末尾
public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); int numNew = a.length; //要添加的元素个数 ensureCapacityInternal(size + numNew); // Increments modCount //扩容 System.arraycopy(a, 0, elementData, size, numNew); //添加 size += numNew; return numNew != 0; }
从 index 位置开始,将集合 c 中的元素添加到ArrayList,并不会覆盖掉在index位置原有的值
public boolean addAll(int index, Collection<? extends E> c) { rangeCheckForAdd(index); Object[] a = c.toArray(); int numNew = a.length; ensureCapacityInternal(size + numNew); // Increments modCount int numMoved = size - index; //要移动的元素个数 if (numMoved > 0) System.arraycopy(elementData, index, elementData, index + numNew,numMoved); System.arraycopy(a, 0, elementData, index, numNew); size += numNew; return numNew != 0; }
删除fromIndex到toIndex之间的全部元素
protected void removeRange(int fromIndex, int toIndex) { modCount++; int numMoved = size - toIndex; System.arraycopy(elementData, toIndex, elementData, fromIndex,numMoved); // clear to let GC do its work int newSize = size - (toIndex-fromIndex); for (int i = newSize; i < size; i++) { elementData[i] = null; } size = newSize; }
提供给get()、remove()等方法检查给出的索引值 index 是否越界
private void rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }
提供给add()和add()进行数组越界检查的方法
private void rangeCheckForAdd(int index) { if (index > size || index < 0) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }
返回异常消息,用于传给IndexOutOfBoundsException
private String outOfBoundsMsg(int index) { return "Index: "+index+", Size: "+size; }
移除list中和c中共有的元素
public boolean removeAll(Collection<?> c) { return batchRemove(c, false); }
只保留list和集合c中公有的元素
public boolean retainAll(Collection<?> c) { return batchRemove(c, true); }
批量删除
private boolean batchRemove(Collection<?> c, boolean complement) { final Object[] elementData = this.elementData; int r = 0, w = 0; boolean modified = false; try { for (; r < size; r++) if (c.contains(elementData[r]) == complement) elementData[w++] = elementData[r]; } finally { // Preserve behavioral compatibility with AbstractCollection, // even if c.contains() throws. if (r != size) { System.arraycopy(elementData, r, elementData, w, size - r); w += size - r; } if (w != size) { // clear to let GC do its work for (int i = w; i < size; i++) elementData[i] = null; modCount += size - w; size = w; modified = true; } } return modified; }
序列化函数
private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException{ // Write out element count, and any hidden stuff int expectedModCount = modCount; s.defaultWriteObject(); // Write out size as capacity for behavioural compatibility with clone() s.writeInt(size); //写入ArrayList大小 // Write out all elements in the proper order. for (int i=0; i<size; i++) { //写入存储的元素 s.writeObject(elementData[i]); } if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } }
private void readObject(java.io.ObjectInputStream s)throws java.io.IOException, ClassNotFoundException { //先将ArrayList的容量读出,然后将所有的元素值读出 elementData = EMPTY_ELEMENTDATA; // Read in size, and any hidden stuff s.defaultReadObject(); // Read in capacity s.readInt(); // ignored //从输入流中读取ArrayList的size if (size > 0) { // be like clone(), allocate array based upon size not capacity ensureCapacityInternal(size); Object[] a = elementData; // Read in all elements in the proper order. for (int i=0; i<size; i++) { //从输入流中将所有的元素值读出 a[i] = s.readObject(); } } }
返回一个ListIterator
public ListIterator<E> listIterator(int index) { if (index < 0 || index > size)throw new IndexOutOfBoundsException("Index: "+index); return new ListItr(index); }
返回一个Iterator迭代器,该迭代器是fail-fast机制的
public Iterator<E> iterator() { return new Itr(); }
private class Itr implements Iterator<E> { int cursor; // index of next element to return //下一个返回元素的索引,默认值为0 int lastRet = -1; // index of last element returned; -1 if no such //上一个返回元素的索引,若没有上一个元素,则为-1 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]; }
ListItr继承Itr,实现ListIterator接口,可以进行双向移动,可以添加元素(有add()方法)
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; }
获取 cursor 前一个元素的索引
public int previousIndex() { return cursor - 1; }
返回 cursor 前一元素
@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 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(); } } }
获取从fromIndex到toIndex之间的子集合
public List<E> subList(int fromIndex, int toIndex) { subListRangeCheck(fromIndex, toIndex, size); //合法性检查 return new SubList(this, 0, fromIndex, toIndex); }
static void subListRangeCheck(int fromIndex, int toIndex, int size) { if (fromIndex < 0) //越界检查 throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); if (toIndex > size) throw new IndexOutOfBoundsException("toIndex = " + toIndex); if (fromIndex > toIndex) //非法参数检查 throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")"); }
嵌套内部类,继承AbstractList,实现RandomAccess接口
private class SubList extends AbstractList<E> implements RandomAccess { private final AbstractList<E> parent; private final int parentOffset; private final int offset; int size; SubList(AbstractList<E> parent, int offset, int fromIndex, int toIndex) { this.parent = parent; this.parentOffset = fromIndex; this.offset = offset + fromIndex; this.size = toIndex - fromIndex; this.modCount = ArrayList.this.modCount; }
设置新值,返回旧值
public E set(int index, E e) { rangeCheck(index); checkForComodification(); E oldValue = ArrayList.this.elementData(offset + index); ArrayList.this.elementData[offset + index] = e; return oldValue; }取值
public E get(int index) { rangeCheck(index); checkForComodification(); return ArrayList.this.elementData(offset + index); }
添加元素
public void add(int index, E e) { rangeCheckForAdd(index); checkForComodification(); parent.add(parentOffset + index, e); //对子类添加元素,是直接操作父类添加的 this.modCount = parent.modCount; this.size++; }
删除元素
public E remove(int index) { rangeCheck(index); checkForComodification(); E result = parent.remove(parentOffset + index); //对子类删除元素,是直接操作父类删除的 this.modCount = parent.modCount; this.size--; return result; }
范围删除
protected void removeRange(int fromIndex, int toIndex) { checkForComodification(); parent.removeRange(parentOffset + fromIndex, parentOffset + toIndex); this.modCount = parent.modCount; this.size -= toIndex - fromIndex; }
返回一个迭代器
public Iterator<E> iterator() { return listIterator(); }
- ArrayList 源码解析
- ArrayList源码解析
- android源码解析 -- ArrayList
- ArrayList源码解析
- ArrayList源码解析
- ArrayList源码解析
- ArrayList源码解析
- ArrayList LinkedList源码解析
- ArrayList 源码解析
- ArrayList集合源码解析
- ArrayList源码解析
- ArrayList类源码解析
- ArrayList源码解析
- ArrayList源码解析
- ArrayList 部分源码解析
- ArrayList源码解析
- ArrayList源码解析
- ArrayList源码解析
- 简单几句JavaScript代码实现图片延迟加载并淡入淡出显示效果
- [web]Node.js入门
- 【考研】第八周总结
- 编写jxl
- 我的学习记录12
- ArrayList源码解析
- Android api level对照表
- log4j使用方法
- Mycat配置读写分离
- 设计模式之----建造者模式(AlertDialog源码分析)
- spring事物处理2
- linux 进程的创建和加载
- 欲重生, 必先浴火
- java温习中封装,继承,多态值得注意的小点