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 类型的 ...
随机推荐
- tableau用户分类
1.观察消费金额的分布 直接[消费金额]直方图趋势不明显的时候,可以考虑将金额对数化处理 这样看起来就近似个正态分布了 2.怎么看超市卖的最好的产品 更深层次的分析怎么做呢? 这个聚合字段在数据源不会 ...
- 解Bug之路-dubbo流量上线时的非平滑问题
前言 笔者最近解决了一个困扰了业务系统很久的问题.这个问题只在发布时出现,每次只影响一两次调用,相较于其它的问题来说,这个问题有点不够受重视.由于种种原因,使得这个问题到了业务必须解决的程度,于是就到 ...
- 蒲公英 · JELLY技术周刊 Vol.17: 90 行代码实现 React Hooks
蒲公英 · JELLY技术周刊 Vol.17 React Hooks 相信大家都不陌生,自被设计出以来就备受好评,在很多场景中都有极高的使用率,其中原理更是很多大厂面试中的必考题,很多朋友都能够如数家 ...
- Vue在v-for中给css传递一个数组参数
需求就是将很多个数据,以进度条的形式展示在页面上,形成一个可视化. 接下来是html代码 <!DOCTYPE html> <html> <head> <tit ...
- 浏览器自动化的一些体会7 selenium webdriver的一些问题
1. 下载图片 这个链接说得最好,差不多所有可能的方法都列举了,除了没有提到用URLDownloadToFile,不过这和用WebClient差不多. https://stackoverflow.co ...
- Jmeter逻辑控制器之If Controller的使用解析
一.If Controller概述 类似于编程语言中if语句,根据给定表达式的值决定是否执行该节点下的子节点,表达式的值 为true则执行,为false则不执行,默认使用javascript语法进行判 ...
- graphics.h源代码下载
graphics.h源代码下载 /*graphics.h DefinitionsforGraphicsPackage. Copyright(c)BorlandInternational1987,198 ...
- 一文说通Jwt、Session、Cooike区别
JWT 全称是 JSON Web Token,是目前非常流行的跨域认证解决方案,在单点登录场景中经常使用到. 有些人觉得它非常好用,用了它之后就不用在服务端借助 redis 实现认证过程了,但是,还有 ...
- 简单的股票信息查询系统 1 程序启动后,给用户提供查询接口,允许用户重复查股票行情信息(用到循环) 2 允许用户通过模糊查询股票名,比如输入“啤酒”, 就把所有股票名称中包含“啤酒”的信息打印出来 3 允许按股票价格、涨跌幅、换手率这几列来筛选信息, 比如输入“价格>50”则把价格大于50的股票都打印,输入“市盈率<50“,则把市盈率小于50的股票都打印,不用判断等于。
'''需求:1 程序启动后,给用户提供查询接口,允许用户重复查股票行情信息(用到循环)2 允许用户通过模糊查询股票名,比如输入“啤酒”, 就把所有股票名称中包含“啤酒”的信息打印出来3 允许按股票价格 ...
- cinder 卷迁移进度的代码分析
一.cinder-api服务的入口函数 D:\code-program\cinder-ocata_cinder\cinder\api\contrib\admin_actions.py from cin ...