ArrayList源码分析(1.7.0_80)
来源:互联网 发布:软件项目任务书 编辑:程序博客网 时间:2024/06/15 20:23
定义
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
底层实现:数组
- AbstractList 实现List的基本操作
- List 定义List的基本方法
- RandomAccess 一种标志位,类似于clone标志,作用:
JDK中说的很清楚,在对List特别是Huge size的List的遍历算法中,要尽量来判断是属于RandomAccess(如ArrayList)还是Sequence List (如LinkedList),因为适合RandomAccess List的遍历算法,用在Sequence List上就差别很大,常用的作法就是:
要作一个判断:
if (list instance of RandomAccess) {
for(int m = 0; m < list.size(); m++){}
}else{
Iterator iter = list.iterator();
while(iter.hasNext()){}
}
参考这里
属性
private transient Object[] elementData;
transient :此字段是否可以被序列化
elementData : ArrayList底层实现数组,初始大小10
方法
trimToSize
public void trimToSize() { modCount++; if (size < elementData.length) { elementData = Arrays.copyOf(elementData, size); } }
作用:重新定义数组初始化大小
modCount:list被改变次数,定义在iterator中,用以判断list是否被同步修改,所以ArrayList不是同步安全的,可以使用以下代码包装一次list使其成为同步安全的:
List list = Collections.synchronizedList(new ArrayList(...));
/** * The modCount value that the iterator believes that the backing * List should have. If this expectation is violated, the iterator * has detected concurrent modification. */ int expectedModCount = modCount;
若两者不相等抛出ConcurrentModificationException异常
重新定义数组大小,只是用来定义数组的容量,不代表数组中有多少个元素,所以
public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; }
用以上方法初始化ArrayList不能初始化ArrayList大小,一般用来当ArrayList数据较大时使用,避免ArrayList底层数组替换。
add(E e)
在list末尾添加元素
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
ensureCapacityInternal:判断是否需要扩容并扩容,modCount自增1
elementData[size++] = e; 新增元素加入数组
扩容方法:
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); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); }
扩容:newCapacity = oldCapacity + (oldCapacity >> 1) 一次扩容一半,至于为什么每次扩容1.5倍,效率问题,扩容之后并将源数据copy到新数组中。
add(int index, E element)
在指定位置添加元素
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++; }
rangeCheckForAdd: 检查下标是否越界
System.arraycopy:将数组中index至末尾数据右移,耗时
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
将数组src中以srcPos开始长度为length的数据复制到dest中,从destPos开始粘贴;
余下add方法都是以以上两种方法为基础
contains(Object o)
数组中是否包含o,正序查找
indexOf(Object o)
返回list中第一次出现o的下标,正序查找,无返回-1。
lastIndexOf(Object o)
返回list从末尾第一次出现o的下标,逆序查找,无返回-1。
clone()
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的clone属于浅拷贝,从这句v.elementData = Arrays.copyOf(elementData, size);
ArrayList的clone只是将原数组中数据的地址复制到新数组中
参考博文:
链接一
链接二
- ArrayList源码分析(1.7.0_80)
- LinkedList源码分析(1.7.0_80)
- HashMap源码分析(1.7.0_80)
- ArrayList(一)源码分析
- flexsim4.0_80实体
- ArrayList源码分析(基于JDK1.6)
- ArrayList源码分析(基于JDK1.6)
- ArrayList源码分析(基于JDK1.6)
- ArrayList源码分析(基于JDK1.6)
- ArrayList源码分析(jdk1.8)
- ArrayList源码分析(Java&Android)
- ArrayList源码分析(JDK1.8)
- ArrayList部分源码分析(基于1.8)
- ArrayList源码分析(基于JDK8)
- ArrayList源码分析(JDK1.8)
- java集合(2):ArrayList源码分析
- Java 集合(1)----- ArrayList 源码分析
- JDK源码分析之ArrayList(一)
- MYIR-ZYNQ7000系列-zturn教程(1)-从新建工程到下载bit文件
- 185. Department Top Three Salaries
- 设计模式--单例模式(Singleton)
- 全志R16平台tinav2.1系统下调通rtl8188eu(草稿)
- jdbc总结
- ArrayList源码分析(1.7.0_80)
- IAR的const,变量指定绝对地址,函数指定存取区域
- hdu1253 胜利大逃亡
- Python3 Scrapy 安装方法
- forName()、newInstance()、getMethod()、getClass()、invoke()理解说明
- packageOfficialDebug和resourceFile does not exist.
- 字符混编---动态规划
- Python3 SciPy解常微分方程 用Matplotlib演示
- 柱状图绘制