ArrayList源码分析笔记(jdk1.8)
1.特点:
ArrayList
是一个动态数组,它是线程不安全的,允许元素为null
可重复,插入有序
读写快,增删慢
扩容:默认容量 10,默认扩容1.5倍
建议指定容量大小,减少扩容带来的性能消耗
2.构造方法
只分析复杂的
public ArrayList(Collection<? extends E> c)
c.toArray() 在Collection接口中定义的接口方法,ArrayList中调用的是Arrays.copyOf(elementData, size)方法(注:扩容也是使用此方法,高频率方法),调用的是System.arraycopy
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
2.add
每次 add之前,都会判断add后的容量,是否需要扩容
默认扩容倍数1.5倍,如果扩容1.5倍后小于传入的容量大小,则使用传入的容量大小,单最大不能大于Integer.MAX_VALUE;
每次扩容都会修改modCount
public boolean add(E e)
public void 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); //将index开始的数据 向后移动一位
elementData[index] = element;
size++;
}
addAll同理都需要先判断ensureCapacityInternal方法进行判断是否需要扩容,然后System.arraycopy进行数组赋值扩容
3.romove
public E remove(int index)
public boolean remove(Object o)
都是通过System.arraycopy进行数组赋值来达到效果,删除后原来,尾部元素,置空,gc
public boolean removeAll(Collection<?> c)
通过循环,和w标记,保存两个集合的非共有元素,共有元素置为null,gc
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;
}
4.set和get
modCount不会改变,效率高
5.迭代器
public Iterator<E> iterator() { return new Itr(); }
内部类:private class Itr implements Iterator<E>
modCount != expectedModCount会抛出并发修改异常ConcurrentModificationException
先next,再remove(实质上是删除上一次next的元素),否则回报IllegalStateException异常
6.与Vector区别
Vector:线程安全,都在方法上加synchronized关键字
扩容:默认容量10,默认2倍扩容
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
https://blog.csdn.net/zxt0601/article/list/2
https://blog.csdn.net/ljcITworld/article/details/52041836
ArrayList源码分析笔记(jdk1.8)的更多相关文章
- ArrayList源码分析笔记
ArrayList源码分析笔记 先贴出ArrayList一些属性 public class ArrayList<E> extends AbstractList<E> imple ...
- ArrayList 源码分析(JDK1.8)
ArrayList简介 ArrayList 是一个数组队列,相当于 动态数组.与Java中的数组相比,它的容量能动态增长.它继承于AbstractList,实现了List, RandomAccess ...
- ArrayList源码分析(JDK1.8)
概述 ArrayList底层是基于数组实现的,并且支持动态扩容的动态数组(变长的集合类).ArrayList允许空值和重复的元素,当向ArrayList中添加元素数量大于其底层数组容量时,会通过扩容机 ...
- ArrayList 源码分析 基于jdk1.8:
1:数据结构: transient Object[] elementData; //说明内部维护的数据结构是一个Object[] 数组 成员属性: private static final int ...
- ArrayList源码分析--jdk1.8
ArrayList概述 1. ArrayList是可以动态扩容和动态删除冗余容量的索引序列,基于数组实现的集合. 2. ArrayList支持随机访问.克隆.序列化,元素有序且可以重复. 3. ...
- ArrayList源码解读(jdk1.8)
概要 上一章,我们学习了Collection的架构.这一章开始,我们对Collection的具体实现类进行讲解:首先,讲解List,而List中ArrayList又最为常用.因此,本章我们讲解Arra ...
- java集合系列之ArrayList源码分析
java集合系列之ArrayList源码分析(基于jdk1.8) ArrayList简介 ArrayList时List接口的一个非常重要的实现子类,它的底层是通过动态数组实现的,因此它具备查询速度快, ...
- zeromq源码分析笔记之线程间收发命令(2)
在zeromq源码分析笔记之架构说到了zmq的整体架构,可以看到线程间通信包括两类,一类是用于收发命令,告知对象该调用什么方法去做什么事情,命令的结构由command_t结构体确定:另一类是socke ...
- Java集合干货——ArrayList源码分析
ArrayList源码分析 前言 在之前的文章中我们提到过ArrayList,ArrayList可以说是每一个学java的人使用最多最熟练的集合了,但是知其然不知其所以然.关于ArrayList的具体 ...
随机推荐
- 02-HTML5新的input属性
本节重点 HTML5 拥有多个新的表单输入类型.这些新特性提供了更好的输入控制和验证 本节介绍新的输入类型: date datetime datetime-local email month numb ...
- UML简单熟悉
+ :代表public - :代表private # :代表protected 实现,继承关系:implements,extends 关联关系:使一个类知道另一个类的属性和方法 每一个Driver类 ...
- JS面试题(二)(常见算法编程)
1.字符串转驼峰 例如:border-bottom-color ----> borderBottomColor var str="border-bottom-color"; ...
- idea tomcat上传图片,无法显示的问题解决
真是浪费时间啊,之前eclipse下的tomcat 去webapps下找就行了,这倒好,idea下根本没有. 我上传的目录建在项目中的static中了,upload文件夹,上传到这里肯定是找不到了的: ...
- C# 多窗体之间方法调用
看似一个简单的功能需求,其实很多初学者处理不好的,很多朋友会这么写: //父窗体是是frmParent,子窗体是frmChildA //在父窗体中打开子窗体 frmChildA child = new ...
- mySql插入网页地址失败
如题:插入的网页地址失败,只显示了开头10位字符.以为是特殊字符的问题. 后来发现是字符串长度不够: ALTER TABLE `news` MODIFY COLUMN `from` VARCHAR( ...
- json遍历 分别使用【原】
json遍历 一 使用org.json.JSONObject遍历 之后的所有遍历都参考了:http://blog.csdn.net/u010648555/article/details/4981538 ...
- Neural Networks and Deep Learning 课程笔记(第三周)浅层神经网络(Shallow neural networks)
3.1 神经网络概述(Neural Network Overview ) (神经网络中,我们要反复计算a和z,最终得到最后的loss function) 3.2 神经网络的表示(Neural Netw ...
- JAVA实现二叉树(简易版--实现了二叉树的各种遍历)
1,个人感觉二叉树的实现主要还是如何构造一颗二叉树.构造二叉树函数的设计方法多种多样,本例采用 addNode 方法实现.以下程序通过定义内部类来表示二叉树的结点,然后再实现了二叉树这种数据结构的一些 ...
- Kettle 中转换(transformation)的执行过程
1,Spoon.java的main方法是整个Kettle运行的入口.当打开Kettle的设计器界面后,可以在其中设计作业和转换.这里讨论转换的执行过程. 2,设计好一个转换后,转换保存的本地文件是 . ...