ArrayList源码解读
来源:互联网 发布:robotmaster软件下载 编辑:程序博客网 时间:2024/06/05 02:04
一、 ArrayList概述:
ArrayList是基于数组实现的,是一个动态数组,所谓动态,就是它的容量会自动增加,ArrayList的初始容量是10。ArrayList不是线程安全的,ArrayList实现了Serializable接口,支持序列化。
二、 ArrayList的实现:
1、私有属性
private static final int DEFAULT_CAPACITY = 10;//默认初始容量private static final Object[] EMPTY_ELEMENTDATA = {};//用于空实例的共享空数组实例private transient Object[] elementData;//elementData存储ArrayList内的元素private int size;//size表示ArrayList包含的元素的数量
2、构造方法
//使用初始容量构造一个空的ArrayList,容量为10;public ArrayList() { super(); this.elementData = EMPTY_ELEMENTDATA; }//构造一个initialCapacity大小的ArrayList,当initialCapacity<0时,抛出IllegalArgumentException异常。public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; }//构造一个包含指定collection的元素的列表,这些元素按照该collection的迭代器返回它们的顺序排列的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) elementData = Arrays.copyOf(elementData, size, Object[].class); }
3、一些方法
// 用指定的元素替代此列表中指定位置上的元素,并返回以前位于该位置上的元素public E set(int index, E element) { rangeCheck(index); E oldValue = elementData(index); elementData[index] = element; return oldValue; }// 将指定的元素添加到此列表的尾部public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }//将指定的元素插入此列表中的指定位置,如果当前位置有元素,则向右移动当前位于该位置的元素以及所有后续元素(将其索引加1)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++; }//按照指定collection的迭代器所返回的元素顺序,将该collection中的所有元素添加到此列表的尾部 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; }//从指定的位置开始,将指定collection中的所有元素插入到此列表中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; } // 返回此列表中指定位置上的元素 public E get(int index) { RangeCheck(index); return (E) elementData[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) { // 由于ArrayList中允许存放null,因此下面通过两种情况来分别处理。 if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { // 类似remove(int index),移除列表中指定位置上的元素。 fastRemove(index); return true; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); return true; } } return false; } }//扩容时,会将原数组中的元素重新拷贝一份到新的数组中,每次数组容量的增长大约是其原容量的1.5倍。//这种操作的代价是很高的,因此在实际使用时,我们应该尽量避免数组容量的扩张。//当我们可预知要保存的元素的多少时,要在构造ArrayList实例时,就指定其容量,以避免数组扩容的发生。//或者根据实际需求,通过调用ensureCapacity方法来手动增加ArrayList实例的容量。public void ensureCapacity(int minCapacity) { int minExpand = (elementData != EMPTY_ELEMENTDATA) // 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) { ensureExplicitCapacity(minCapacity); } }//删除Arraylist中所有元素,删除之后,剩下一个空的ArrayListpublic void clear() { modCount++; // clear to let GC do its work for (int i = 0; i < size; i++) elementData[i] = null; size = 0; }
三、总结
1、关于ArrayList和Vector区别如下:
ArrayList在内存不够时默认是扩展50% + 1个,Vector是默认扩展1倍。
Vector提供indexOf(obj, start)接口,ArrayList没有。
Vector属于线程安全级别的,但是大多数情况下不使用Vector,因为线程安全需要更大的系统开销。
2、注意其三个不同的构造方法。无参构造方法构造的ArrayList的容量默认为10,带有Collection参数的构造方法,将Collection转化为数组赋
给ArrayList的实现数组elementData。
3、ArrayList的实现中大量地调用了Arrays.copyof()和System.arraycopy()方法。Arrays.copyof()实际上是在其内部又创建了一个长度为
newlength的数组,调用System.arraycopy()方法,将原来数组中的元素复制到了新的数组中。System.arraycopy()方法被标记了native,调用
了系统的C/C++代码,在JDK中是看不到的,但在openJDK中可以看到其源码。该函数实际上最终调用了C语言的memmove()函数,因此它可以保证
同一个数组内元素的正确复制和移动,比一般的复制方法的实现效率要高很多,很适合用来批量处理数组。Java强烈推荐在复制大量数组元素时
用该方法,以取得更高的效率。
4、ArrayList基于数组实现,可以通过下标索引直接查找到指定位置的元素,因此查找效率高,但每次插入或删除元素,就要大量地移动元素,
插入删除元素的效率低。
5、在查找给定元素索引值等的方法中,源码都将该元素的值分为null和不为null两种情况处理,ArrayList中允许元素为null。
- Java--ArrayList源码解读
- ArrayList源码解读
- Java源码解读-ArrayList
- ArrayList源码解读
- ArrayList源码解读
- ArrayList源码解读
- ArrayList源码解读
- ArrayList详解,源码解读
- ArrayList源码简略解读
- ArrayList扩容源码解读
- ArrayList源码解读
- ArrayList JDK9源码解读
- ArrayList源码解读
- JDK之ArrayList源码解读
- ArrayList底层实现源码解读
- 1.7版本 Arraylist源码解读
- jdk 1.8 arraylist源码解读
- Java 2源码解读:java.util.ArrayList
- Component Tree
- CF 2B The least round way
- Qt多窗口来回切换实战
- 用verilog设计一个交通信号灯,要求有红,黄,绿,左转四盏灯
- Java数据结构——线性表的顺序存储实现
- ArrayList源码解读
- 正则表达式的逻辑关系
- 处理使用selenium模块时常见的WebdriverException
- HDU 1509 Windows Message Queue(优先队列)
- I,P,B帧和PTS,DTS的关系
- 获取文件夹路径、在指定地点新建文件夹、在路径中加“\”函数。
- JDK动态代理生成.class文件和cglib动态代理生成.class文件
- 用random模块获取随机数
- BZOJ 3343 教主的魔法