ArrayList 源码分析 基于jdk1.8:
1:数据结构:
transient Object[] elementData; //说明内部维护的数据结构是一个Object[] 数组
成员属性:
private static final int DEFAULT_CAPACITY = 10;
private static final Object[] EMPTY_ELEMENTDATA = {}; //空数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; //默认空数组
transient Object[] elementData; //维护数组的引用
private int size; //数组长度
2:构造方法:
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; //构造长度为0的Object[] 赋值给elementData,用于后面保存数据
}
3:主要方法的分析: add get remove add(int index,Object o)
1) add: 以添加第一个元素为例
public boolean add(E e) { e=”aa”
ensureCapacityInternal(size + 1); // size=0
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) { // minCapacity=1
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { //第一个元素 true
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); //取 DEFAULT_CAPACITY
}
ensureExplicitCapacity(minCapacity);
}
下面进入ensureExplicitCapacity 分析
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0) //10-0=10
grow(minCapacity); //进入扩容的方法
}
以下是扩容的方法:
private void grow(int minCapacity) { // minCapacity=10
// overflow-conscious code
int oldCapacity = elementData.length; // oldCapacity=0
int newCapacity = oldCapacity + (oldCapacity >> 1); //移位操作,移位后newCapacity=0
if (newCapacity - minCapacity < 0) //0-10=-10
newCapacity = minCapacity; // newCapacity=10
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); //将旧数组中的内容拷贝到新的数组中 并且将新的数组赋值给elementData
}
扩容机制:
int newCapacity = oldCapacity + (oldCapacity >> 1); //将新数组扩容为原先数组的1.5倍长度
2):add(int index,Object o)方法分析
主要的实现方法如下:
public void add(int index, E element) { // index1
rangeCheckForAdd(index); //和add方法里的一直
ensureCapacityInternal(size + 1); //和add方法里的一直
System.arraycopy(elementData, index, elementData, index + 1,
size - index); //主要是这里实现的index后面元素的拷贝
elementData[index] = element;
size++;
}
下面分析这句代码实现的效果
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
原始数组的结构和数据:
System.arraycopy方法执行后的数据结构
将 b2,b3 往后复制元素
最后将index处的元素赋值
elementData[index] = element;
这就是在具体索引进行add
的方法,往后的元素进行拷贝,导致消耗比较大
3):get方法:
public E get(int index) {
rangeCheck(index); //检查数组是否越界
return
elementData(index); //返回数组的index 索引出的元素
}
Get 方法比较简单,就不做过多分析了
ArrayList 源码分析 基于jdk1.8:的更多相关文章
- HashMap 源码分析 基于jdk1.8分析
HashMap 源码分析 基于jdk1.8分析 1:数据结构: transient Node<K,V>[] table; //这里维护了一个 Node的数组结构: 下面看看Node的数 ...
- CopyOnWriteArrayList 源码分析 基于jdk1.8
CopyOnWriteArrayList 源码分析: 1:成员属性: final transient ReentrantLock lock = new ReentrantLock(); //内部是 ...
- ArrayList 源码分析(JDK1.8)
ArrayList简介 ArrayList 是一个数组队列,相当于 动态数组.与Java中的数组相比,它的容量能动态增长.它继承于AbstractList,实现了List, RandomAccess ...
- ArrayList源码分析(JDK1.8)
概述 ArrayList底层是基于数组实现的,并且支持动态扩容的动态数组(变长的集合类).ArrayList允许空值和重复的元素,当向ArrayList中添加元素数量大于其底层数组容量时,会通过扩容机 ...
- HashMap源码分析-基于JDK1.8
hashMap数据结构 类注释 HashMap的几个重要的字段 hash和tableSizeFor方法 HashMap的数据结构 由上图可知,HashMap的基本数据结构是数组和单向链表或红黑树. 以 ...
- ArrayList的源码分析(基于jdk1.8)
1.初始化 transient Object[] elementData; //实际存储元素的数组 private static final Object[] DEFAULTCAPACITY_EMPT ...
- LinkedList的源码分析(基于jdk1.8)
1.初始化 public LinkedList() { } 并未开辟任何类似于数组一样的存储空间,那么链表是如何存储元素的呢? 2.Node类型 存储到链表中的元素会被封装为一个Node类型的结点.并 ...
- ArrayList源码解读(jdk1.8)
概要 上一章,我们学习了Collection的架构.这一章开始,我们对Collection的具体实现类进行讲解:首先,讲解List,而List中ArrayList又最为常用.因此,本章我们讲解Arra ...
- ArrayList源码分析--jdk1.8
ArrayList概述 1. ArrayList是可以动态扩容和动态删除冗余容量的索引序列,基于数组实现的集合. 2. ArrayList支持随机访问.克隆.序列化,元素有序且可以重复. 3. ...
随机推荐
- Delphi CreateProcess
Delphi CreateProcess WIN32API函数CreateProcess用来创建一个新的进程和它的主线程,这个新进程运行指定的可执行文件 2010-12-27 17:00:17| 分 ...
- Laravel 创建指定表 migrate
解决方案:打开创建表的那个 migration 文件,在创建表的方法执行之前加一个判断条件 if (!Schema::hasTable('password_resets')) { Schema::cr ...
- mpvue小程序开发之 实现一个弹幕评论
先上图 就是一个简单的弹幕发送功能 弹幕区的页面: <div class="content" v-show="doommData.length"> ...
- Alpha七天冲刺
一. 原计划冲刺甘特图 二. 七天冲刺博客 1. https://www.cnblogs.com/liujiamei/p/11870107.html 2. https://www.cnblogs.co ...
- [b0009] 玩Hadoop中碰到的各种错误
1. Error: java.lang.RuntimeException: java.lang.ClassNotFoundException: Class mp.filetest.WordCount2 ...
- JS高阶---作用域面试
面试题1: ,答案为10 有一点需要明确:作用域是在定义编写代码时已经决定好的 面试题2: 结果1: 结果2: 首先在内部作用域找,没有 然后在全局作用域找,window没有,所以会报错 如果想找对象 ...
- 【餐厅】 What kind of food would you like to eat tonight?
核心句型 What kind of food would you like to eat tonight? 你今晚想吃哪种菜? What would you like to eat ? 你想吃什么? ...
- Python类的使用总结
Python是一个面向对象的解释型语言,所以当然也有类的概念.在Python中,所有数据类型都可以视为对象,当然也可以自定义对象.自定义的对象数据类型就是面向对象中的类(Class)的概念.之前接触类 ...
- c# 第七节 编程规范,vs中的各种设置
本节内容: 1:编程规范 2:vs中的各种设置 3:一个解决方案多个项目的创建.使用 1:编程规范 需要规范的地方: 1: 2: 2:vs中的各种设置 实现: 3:一个解决方案多个项目的创建.使用
- Spring Data Solr创建动态域报错:org.springframework.data.solr.UncategorizedSolrException
今天在项目中使用Spring Data Solr导入动态域数据报错, 控制台打印错误信息如下 Exception in thread "main" org.springframew ...