java集合类源码学习三——ArrayList
ArrayList无疑是java集合类中的一个巨头,而且或许是使用最多的集合类。ArrayList继承自AbstractList抽象类,实现了List<E>, RandomAccess, Cloneable, java.io.Serializable这些接口,这意味着ArrayList可以随机取数据,支持浅拷贝和序列化。ArrayList可以存放各种类型的值,有序、可重复而且可以存放null,这里的有序指的是按顺序存放,而不是自动排序。它有一个默认容量DEFAULT_CAPACITY = 10,还定义了两个空数组EMPTY_ELEMENTDATA和DEFAULTCAPACITY_EMPTY_ELEMENTDATA,同样都是静态私有不可变的Object数组,那么为什么要弄两个,从取名上看EMPTY_ELEMENTDATA指的是空数组,而DEFAULTCAPACITY_EMPTY_ELEMENTDATA指的是默认容量的未存放元素的空数组。从后面的代码可以看出,给数组长度赋默认值之前,是与DEFAULTCAPACITY_EMPTY_ELEMENTDATA比较的,而让数组为空数组则是与EMPTY_ELEMENTDATA比较的,如果非要说有差别,也就这点了,有点脱裤子放屁的意味。然后定义了一个object数组elementData,用transient修饰的,表示不可以被序列化,这就是ArrayList的底层实现,本质是个数组。提供了三个构造器,一个无参,一个可指定长度,还有一个可将其他Collection的集合转化成ArrayList,下面是第三个构造器的代码
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
里面有个判断class的操作,用于把从其他集合转到数组的非Object类型转化成Object类型数组。ArrayList底层既然是数组,那么最大长度也就为Integer的最大值减8,同样在扩容的时候如果这个长度不够,可以用hugeCapacity,也即Integer的最大值。下面是插入到一个位置和获取一个位置的值的代码
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++;
} public E get(int index) {
rangeCheck(index); return elementData(index);
}
可以看到,插入元素需要把该位置及后面的元素全部往后移一位,时间复杂度为O(n),而获取一个元素,只需要根据索引定位过去就行,时间复杂度为O(1)。其余的操作基本就是各种对数组的操作,每次操作都会有一个modCount++,表示修改过一次,用的最多的方法System.arraycopy(Object src, int srcPos,Object dest, int destPos,int length),这是一个native方法,用于快速拷贝一段数组到另一个位置。后面还有迭代器Iterator和listIterator的具体实现,这个之前也分析过了,没什么区别。
后面还有些JDK1.8加的支持函数式编程的方法,先不提。由于ArrayList的方法不是同步的,因此在多线程访问的时候如果有对其进行操作,不是线程安全的。所以在多线程用的时候需要加个同步锁,或者别的线程安全的集合类。
java集合类源码学习三——ArrayList的更多相关文章
- Java集合类源码解析:ArrayList
目录 前言 源码解析 基本成员变量 添加元素 查询元素 修改元素 删除元素 为什么用 "transient" 修饰数组变量 总结 前言 今天学习一个Java集合类使用最多的类 Ar ...
- java集合类源码学习二
我们查看Collection接口的hierarchy时候,可以看到AbstractCollection<E>这样一个抽象类,它实现了Collection接口的部分方法,Collection ...
- java集合类源码学习一
对于java的集合类,首先看张图 这张图大致描绘出了java集合类的总览,两个体系,一个Collection集合体系一个Map集合体系.在说集合类之前,先说说Iterable这个接口,这个接口在jdk ...
- Java集合类源码学习- Iterabel<T>,Colection<E>,AbstractCollection<E>
Collection<E>接口extends Iteratable<E>接口. Iteratable<T>:实现接口使得对象能够成为“for-each loop”的 ...
- Java集合类源码解析:Vector
[学习笔记]转载 Java集合类源码解析:Vector 引言 之前的文章我们学习了一个集合类 ArrayList,今天讲它的一个兄弟 Vector.为什么说是它兄弟呢?因为从容器的构造来说,Vec ...
- Java集合类源码解析:HashMap (基于JDK1.8)
目录 前言 HashMap的数据结构 深入源码 两个参数 成员变量 四个构造方法 插入数据的方法:put() 哈希函数:hash() 动态扩容:resize() 节点树化.红黑树的拆分 节点树化 红黑 ...
- 集合框架源码学习之ArrayList
目录: 0-0-1. 前言 0-0-2. 集合框架知识回顾 0-0-3. ArrayList简介 0-0-4. ArrayList核心源码 0-0-5. ArrayList源码剖析 0-0-6. Ar ...
- Java集合源码学习(一)集合框架概览
>>集合框架 Java集合框架包含了大部分Java开发中用到的数据结构,主要包括List列表.Set集合.Map映射.迭代器(Iterator.Enumeration).工具类(Array ...
- java Integer 源码学习
转载自http://www.hollischuang.com/archives/1058 Integer 类在对象中包装了一个基本类型 int 的值.Integer 类型的对象包含一个 int 类型的 ...
随机推荐
- ECS7天实践进阶训练营Day5:使用ECS自建云端下载服务器
一.概述 CCAA是服务器离线下载解决方案包,其组件中包含了Aria2提供了离线下载功能,能支持HTTP/HTTPS/FTP/BT/磁力链下载等常用离线下载模式及断点续传等功能.ccaa_web支撑于 ...
- 详解POW工作量证明原理
原文地址 来自 微信公众号 区块链大师 POW工作量证明(英文全称为Proof of Work)早在比特币出现之前就已经有人探索,常见的是利用HASH运算的复杂度进行CPU运算实现工作量确定,当然你 ...
- Java实现token的生成与验证-登录功能
一.token与cookie相比较的优势1.支持跨域访问,将token置于请求头中,而cookie是不支持跨域访问的: 2.无状态化,服务端无需存储token,只需要验证token信息是否正确即可,而 ...
- .NET 跨平台框架Avalonia UI: 填坑指北(二):在Linux上跑起来了
上一章回顾: .NET 跨平台框架Avalonia UI: 填坑指北(一):熟悉UI操作 本篇将要阐述 包括但不仅限于Avalonia及所有Windows到Linux跨平台开发 的一些注意事项: 一 ...
- 【趣味设计模式系列】之【代理模式2--JDK动态代理源码解析】
1. 图解 上图主要描述了JDK动态代理的执行过程,下面做详细分析. 2. Proxy源码分析 上一篇,在使用JDK动态代理的时候,借助于Proxy类,使用newProxyInstance静态方法,创 ...
- windows安装cnpm步骤
1.首先前往nodejs官网下载nodejs 2.安装nodejs 3.打开cmd,输入npm -v,检查npm是否安装成功.成功返回的话返回输出版本号 4.安装cnpm,输入npm install ...
- Mybatis-09-缓存
缓存 什么是缓存[Cache]? 存在内存中的临时数据 提高查询效率,解决高并发的性能问题 为什么使用缓存? 减少和数据库的交互次数,减少系统开销,提高系统效率 什么样的数据能使用缓存? 经常查询且不 ...
- python 在目标位置建立文件夹
import os path = r'D:\pywork\12' # 指定位置 if not os.path.exists(path + '/' + '任务集'): #如果目标位置 不存在该文件夹“任 ...
- sqlalchemy怎么order_by降序/升序并取第一条数据
原文链接:https://blog.csdn.net/mark4541437/article/details/103755721 sqlalchemy怎么order_by降序/升序并取第一条数据 fr ...
- 团队作业4:第六篇Scrum冲刺博客(歪瑞古德小队)
目录 一.Daily Scrum Meeting 1.1 会议照片 1.2 项目进展 二.项目燃尽图 三.签入记录 3.1 代码/文档签入记录 3.2 Code Review 记录 3.3 issue ...