java arraylist源码记录
1. ArrayList 实现了RandomAccess接口, RandomAccess接口用于标记是否可以随机访问
2. 继承了AbstractList类, 因此获取了modcount , modcount用于实现快速失败机制, 如果list有修改, 那么modcount自增
3. ArrayList不支持并发, 是非线程安全的
4. 支持存放null元素
5. 扩容, 每次都是原来大小的1.5倍
public void ensureCapacity(int minCapacity) {
//如果elementData不等于EMPTY_ELEMENTDATA(因为初始化时有可能等于), 那么minExpand为0或者DEFAULT_CAPACITY
//如果elementData不为空minExpand为0, 可以用这个来处理minCapacity为负数的情况
//如果elementData为空, 那么就是默认容量
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;
//如果最小容量大于minExpand, 那么进行明确扩容
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
}
//已确定扩容minCapacity
private void ensureExplicitCapacity(int minCapacity) {
modCount++; //修改次数加1
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
//newCapacity为oldCapacity的1.5倍, 这里有可能会溢出为-1
int newCapacity = oldCapacity + (oldCapacity >> 1);
....
}
6. lastIndexOf, contains, indexOf方法用于查找, 时间复杂度均为O(N), 使用对象的equals方法进行比较
7. clone() 方法为深复制, 所谓深复制和浅复制的区别在于复制内部引用对象时的不同, 深复制会将原来的对象重新clone一份, 让复制对象的引用指向新对象, 而浅复制仅仅复制引用, 仍指向原来的对象. java Object中的clone方法为浅复制
8. set() 和 get() 为O(1)的时间复杂度
9. 调用ensureCapacityInternal(int) 会使modCount+1. ArrayList中的添加元素都会调用这个函数 ,例如add(object)和add(int,Object)
10. add(Object) 和add(int,Object)的时间复杂度为O(N), 因为底层数组的复制移动
11. remove(int)方法也会使modCount+1, 时间复杂度为O(N) , 同时内部使用elementData[--size] = null;用来防止内存泄漏, 以便gc释放内存
12. remove(Object) 使用了fastRemove非法, fastRemove如果未找到删除元素, 那么modCount是不会变的, 反之modCount+1 , 之所以fastRemove称之为fast是因为使用了System.arrayCopy进行元素移动, System.arrayCopy是一个native方法, 可以躲避java访问数组时的下标检查.
13. clear方法, modCount+1
14. addAll(...) 都会调用ensureCapacityInternal方法, 从而使modCount+1, O(N)的时间复杂度
15. removeAll(object)//补集和retainAll(object)//交集 都可以使用batchRemove方法, O(N^2)的时间复杂度, modCount+1.
16. 快速失败机制体现在容器的遍历中, Iterator会在对象初始化过程中保存当前容器的modCount, 并在每次遍历检查modCount, 如果两者不一致, 那么说明容器在遍历时被修改, 抛出ConcurrentModificationException.
private class Itr implements Iterator<E> {
int expectedModCount = modCount;
public E next() {
checkForComodification();
int i = cursor;
...
}
public void remove() {
...
checkForComodification();
...
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
java arraylist源码记录的更多相关文章
- Java ArrayList源码剖析
转自: Java ArrayList源码剖析 总体介绍 ArrayList实现了List接口,是顺序容器,即元素存放的数据与放进去的顺序相同,允许放入null元素,底层通过数组实现.除该类未实现同步外 ...
- Java ArrayList源码分析(有助于理解数据结构)
arraylist源码分析 1.数组介绍 数组是数据结构中很基本的结构,很多编程语言都内置数组,类似于数据结构中的线性表 在java中当创建数组时会在内存中划分出一块连续的内存,然后当有数据进入的时候 ...
- Java ArrayList源码分析(含扩容机制等重点问题分析)
写在最前面 这个项目是从20年末就立好的 flag,经过几年的学习,回过头再去看很多知识点又有新的理解.所以趁着找实习的准备,结合以前的学习储备,创建一个主要针对应届生和初学者的 Java 开源知识项 ...
- Java - ArrayList源码分析
java提高篇(二一)-----ArrayList 一.ArrayList概述 ArrayList是实现List接口的动态数组,所谓动态就是它的大小是可变的.实现了所有可选列表操作,并允许包括 nul ...
- Java——ArrayList源码解析
以下针对JDK 1.8版本中的ArrayList进行分析. 概述 ArrayList基于List接口实现的大小可变的数组.其实现了所有可选的List操作,并且元素允许为任意类型,包括null元 ...
- Java|ArrayList源码分析|add()增加方法和grow()扩容方法
本文结构: 1.介绍特点 2.基本方法 3.重点源码分析 1.介绍特点 ArrayList: 是List的一个具体实现子类,是List接口的一个数组实现 (里面必定维护了一个数组). 默认初始容量10 ...
- java ArrayList源码分析(转载)
1.ArrayList是一个相对来说比较简单的数据结构,最重要的一点就是它的自动扩容,可以认为就是我们常说的“动态数组”. 来看一段简单的代码: 12345 ArrayList<String&g ...
- 【源码阅读】Java集合之一 - ArrayList源码深度解读
Java 源码阅读的第一步是Collection框架源码,这也是面试基础中的基础: 针对Collection的源码阅读写一个系列的文章,从ArrayList开始第一篇. ---@pdai JDK版本 ...
- Java集合源码分析(一)ArrayList
前言 在前面的学习集合中只是介绍了集合的相关用法,我们想要更深入的去了解集合那就要通过我们去分析它的源码来了解它.希望对集合有一个更进一步的理解! 既然是看源码那我们要怎么看一个类的源码呢?这里我推荐 ...
随机推荐
- 洛谷P1418 选点问题
P1418 选点问题 74通过 240提交 题目提供者tinylic 标签云端 难度普及+/提高 时空限制1s / 128MB 提交 讨论 题解 最新讨论更多讨论 非常重要!! 90分的点这里 题 ...
- Failed to apply plugin [id 'com.gradle.build-scan']
把spring源码clone下来之后,使用gradle编译不通过,异常日志如下: FAILURE: Build failed with an exception. * Where: Build fil ...
- jquery 选择器加变量
var $role_id = btn.parent().prev().prev().attr('id') var $department_id = btn.parent().prev().prev() ...
- django前端渲染多对多关系(比如一本书的作者有哪些)
自己遇到的问题是,前端渲染不出多对多关系,咨询Yuan后解决,特此记录. urls.py from django.conf.urls import url from book import views ...
- d3 比例尺
.domain([, ]) 定义域范围 .range([, ]) 值域范围 var scale = d3.scale.linear() .domain([, ]) .range([, ]); 将100 ...
- 30深入理解C指针之---字符串和数组
一.字符串与数组 1.定义:使用字符数组表示字符串 2.特征: 1).可以直接使用字符串字面量初始化字符数组 2).声明后,赋值就只能使用字符串操作函数strcpy函数赋值 3).可以使用数组的一一赋 ...
- dedecms--在后台增加会员添加
最近在研究dedecms需要前台页面不允许会员注册,而会员帐号是管理员在后台添加的,首先我们得在后台的栏目选项中有会员添加这一栏目: 1:在dede/inc的文件夹下面找到inc_memu.php;找 ...
- [深入学习C#]C#实现多线程的方式:Task——任务
简介 .NET 4包含新名称空间System.Threading.Tasks,它 包含的类抽象出了线程功能. 在后台使用ThreadPool. 任务表示应完成的某个单元的工作. 这个单元的工作可以在单 ...
- js、jq平时积累
1.window.onbeforeunload = function(){$(window).scrollTop(0);} //在即将离开当前页面(刷新或关闭)时执行 JavaScript ...
- 前端笔记之Vue(七)Vue-router&axios&Vue插件&Mock.js&cookie|session&加密
一.Vue-router(路由) 1.1路由创建 官网:https://router.vuejs.org/zh/ 用 Vue.js + Vue Router 创建单页应用,是非常简单的.使用 Vue. ...