JDK1.8源码阅读记录ArrayList类
2020-03-22 18:19
453 查看
JDK1.8源码阅读记录
JAVA.Util包
ArrayList类
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
ArrayList类继承AbstractList类,实现了List、RandomAccess、Cloneable、Serializable接口。
ArrayList是一个数组队列,基于数组实现。与普通数组相比,它的容量能动态扩大,简称扩容。本类继承了AbstractList类,实现了List接口,提供了相关的增加、修改、遍历、删除等功能。
它实现了RandomAccess接口,提供了随机访问功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。即我们可以通过索引值快速获取元素对象,跟数组类似。
实现了Cloneable接口,即覆盖了函数clone(),能被克隆。
实现java.io.Serializable接口,这意味着ArrayList支持序列化。
不过,ArrayList不是线程安全的,推荐在单线程中才使用本类。而Vector或者CopyOnWriteArrayList是线程安全的,可以在多线程中使用。
属性
/* * 序列化ID */ private static final long serialVersionUID = 8683452581122892189L; /** * 静态变量,默认容量为10 */ private static final int DEFAULT_CAPACITY = 10; /** * 空数组 */ private static final Object[] EMPTY_ELEMENTDATA = {}; /** * 空数组,如果使用默认构造函数创建,则默认对象内容默认是该值 */ private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; /** * 当前数据对象存放地方,不参与序列化,设置为default是为了简化内部类的访问 */ transient Object[] elementData; /** * 包含的元素数量 */ private int size;
构造方法
/** * 无参构造,空数组 */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } /** * 构造指定容量的对象 */ public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } } /** * 通过Collection对象构造ArrayList */ public ArrayList(Collection<? extends E> c) { elementData = c.toArray();//浅拷贝,只是将由c创建的数组地址赋给elementData if ((size = elementData.length) != 0) { if (elementData.getClass() != Object[].class) //深拷贝,相当于将c里面的对象复制一份到elementData中 elementData = Arrays.copyOf(elementData, size, Object[].class); } else { // replace with empty array. this.elementData = EMPTY_ELEMENTDATA; } }
方法
public void trimToSize() { modCount++; if (size < elementData.length) { elementData = (size == 0) ? EMPTY_ELEMENTDATA : Arrays.copyOf(elementData, size); } }
自增修改次数,比较ArrayList的大小和elementData的长度,如果左边小于右边,则将elementData的长度修剪到ArrayList的大小。
public int size() { //取得大小 return size; } public boolean isEmpty() { //判断是否为空 return size == 0; } public boolean contains(Object o) { //判断是否包含某个对象 return indexOf(o) >= 0; } public int indexOf(Object o) { //查找参数对象的第一个索引值,无则返回-1 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) { //由后向前查找参数对象的最后一个索引值,无则返回-1 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; } public Object[] toArray() { //返回一个包含此列表中所有元素的数组。 return Arrays.copyOf(elementData, size); }
位置访问操作方法
E elementData(int index) { return (E) elementData[index]; } public E get(int index) { rangeCheck(index); return elementData(index); }
返回此列表中指定位置的元素。
改、增、删操作方法
- 改:
public E set(int index, E element)
- 首先检查是否超出范围,然后用elemet替换index处的旧值,返回旧值。
- 增:
public boolean add(E e)
- 在elementData的size处增加element,,即尾部增加,增加成功返回true。
public void add(int index, E element)
- 从index到size-1处的元素向后移一位,然后在index处增加element。
public boolean addAll(Collection<? extends E> c)
- 在ArrayList尾部增加c集合转化的数组,若有增加返回true。
public boolean addAll(int index, Collection<? extends E> c)
- 将index后的元素向后移一位,然后在index处增加c集合转化的数组,若有增加返回true。
- 删:
public E remove(int index)
- 从index到size-1处的元素向前一位(覆盖掉原先的元素),然后在size(大小)-1处的值设为null,返回删除的元素。
public boolean remove(Object o)
- 找到参数第一次在ArrayList出现的位置index,然后从index到size-1处的元素向前一位,后在size(大小)-1处的值设为null,返回删除的元素。
public void clear()
- 清空ArrayList,size为0、
附
- ArrayList自己实现了 private void writeObject(java.io.ObjectOutputStream s)和 private void readObject(java.io.ObjectInputStream s) 方法
- ArrayList基于数组方式实现,无容量的限制(会扩容)
- 添加元素时可能要扩容(所以最好预判一下),删除元素时不会减少容量(若希望减少容量,trimToSize()),删除元素时,将删除掉的位置元素置为null,下次gc就会回收这些元素所占的内存空间。
- 线程不安全
- get(int index):获取指定位置上的元素时,可以通过索引直接获取(O(1))
- remove(Object o)需要遍历数组
- remove(int index)不需要遍历数组,只需判断index是否符合条件即可,效率比remove(Object o)高
- contains(E)需要遍历数组
- 使用iterator遍历可能会引发多线程异常
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- JDK1.8源码阅读记录TreeMap类
- JDK1.8源码阅读记录LinkedHashMap类
- JDK1.8源码阅读记录HashSet类
- JDK1.8源码阅读记录HashMap类
- JDK1.8源码阅读记录LinkedList类
- HashMap源码阅读笔记(基于jdk1.8)
- JDK1.8 -- HashMap源码阅读
- JDK 1.8 HashMap 源码阅读二
- 阅读jdk1.8源码小收获
- JDK1.8源码阅读之——String,StringBuffer, StringBuilder
- 【JDK1.8】JDK1.8集合源码阅读——TreeMap(一)
- Java Jdk1.8 HashMap源码阅读笔记二
- JDK1.8源码阅读系列之三:Vector
- 【JDK1.8】JDK1.8集合源码阅读——LinkedHashMap
- Java基础之源码阅读(一):jdk1.8的HashMap
- JDK 1.8 ArrayBlockingQueue 源码阅读(二)获取
- jdk1.8 J.U.C并发源码阅读------ReentrantLock源码解析
- Java Jdk1.8 HashMap源码阅读
- ArrayList源码阅读jdk1.8
- 【JDK1.8】JDK1.8集合源码阅读——IdentityHashMap