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的更多相关文章

  1. Java集合类源码解析:ArrayList

    目录 前言 源码解析 基本成员变量 添加元素 查询元素 修改元素 删除元素 为什么用 "transient" 修饰数组变量 总结 前言 今天学习一个Java集合类使用最多的类 Ar ...

  2. java集合类源码学习二

    我们查看Collection接口的hierarchy时候,可以看到AbstractCollection<E>这样一个抽象类,它实现了Collection接口的部分方法,Collection ...

  3. java集合类源码学习一

    对于java的集合类,首先看张图 这张图大致描绘出了java集合类的总览,两个体系,一个Collection集合体系一个Map集合体系.在说集合类之前,先说说Iterable这个接口,这个接口在jdk ...

  4. Java集合类源码学习- Iterabel<T>,Colection<E>,AbstractCollection<E>

    Collection<E>接口extends Iteratable<E>接口. Iteratable<T>:实现接口使得对象能够成为“for-each loop”的 ...

  5. Java集合类源码解析:Vector

    [学习笔记]转载 Java集合类源码解析:Vector   引言 之前的文章我们学习了一个集合类 ArrayList,今天讲它的一个兄弟 Vector.为什么说是它兄弟呢?因为从容器的构造来说,Vec ...

  6. Java集合类源码解析:HashMap (基于JDK1.8)

    目录 前言 HashMap的数据结构 深入源码 两个参数 成员变量 四个构造方法 插入数据的方法:put() 哈希函数:hash() 动态扩容:resize() 节点树化.红黑树的拆分 节点树化 红黑 ...

  7. 集合框架源码学习之ArrayList

    目录: 0-0-1. 前言 0-0-2. 集合框架知识回顾 0-0-3. ArrayList简介 0-0-4. ArrayList核心源码 0-0-5. ArrayList源码剖析 0-0-6. Ar ...

  8. Java集合源码学习(一)集合框架概览

    >>集合框架 Java集合框架包含了大部分Java开发中用到的数据结构,主要包括List列表.Set集合.Map映射.迭代器(Iterator.Enumeration).工具类(Array ...

  9. java Integer 源码学习

    转载自http://www.hollischuang.com/archives/1058 Integer 类在对象中包装了一个基本类型 int 的值.Integer 类型的对象包含一个 int 类型的 ...

随机推荐

  1. fetch封装

    import {fetch as fetchPro} from "whatwg-fetch" import qs from "qs" const get=(ur ...

  2. 如何实现数据库CDP,即数据库连续数据保护

    备份可以分为定期备份和实时备份.定期备份与实时备份相比存在两大劣势:一是备份需要时间窗口,对于很多24小时业务运行的机构,线上业务不允许有过多的业务系统停机去进行数据备份:二是定期备份无法保证数据丢失 ...

  3. 使用Python Openssl库解析X509证书信息

    X.509 证书结构描述 常见的X.509证书格式包括: 后缀 作用 cer/crt 用于存放证书,它是2进制形式存放的,不含私钥 pem 以Ascii来表示,可以用于存放证书或私钥. pfx/p12 ...

  4. JavaScript基础-06-正则表达式

    正则表达式 1. 正则表达式用于定义一些字符串的规则:计算机可以根据正则表达式,来检查一个字符串是否符合规则,将字符串中符合规则的内容提取出来. 2. 创建正则表达式对象: var reg=new R ...

  5. 面试中的老大难-mysql事务和锁,一次性讲清楚!

    众所周知,事务和锁是mysql中非常重要功能,同时也是面试的重点和难点.本文会详细介绍事务和锁的相关概念及其实现原理,相信大家看完之后,一定会对事务和锁有更加深入的理解. 本文主要内容是根据掘金小册& ...

  6. webpack打包原理

    什么是 webpack ? 本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler).当 webpack 处理应用程序时,它会递归地构建一个依 ...

  7. 前端面试?这份手撸Promise请你收下

    前言 现在很多大厂面试前端都会要求能够手动的写出一个Promise,所以这里整理了一份手写的Promise. 绝对详细,功能绝对强大.如果你不了解Promise的基本使用,那么本篇文章可能不太适合你, ...

  8. Redis设计与实现——单机数据库的实现

    数据库 服务器中的数据库 redisClient切换数据库 redis客户端默认目标数据库为0号数据库,可以通过SELECT命令来切换目标数据库. 客户端状态redisClient结构的db属性记录了 ...

  9. idea提升效率的插件

    这篇文章用于记录idea插件.多分类记录确实可以提升效率. 1. FindBugs 虽说Idea本身提供的代码检查工具已经很强大了,但Idea提供的更多是规范性的检查,如果需要深入地检查异常,可以使用 ...

  10. Mapreduce之排序&规约&实战案例

    MapReduce 排序和序列化 简单介绍 ①序列化 (Serialization) 是指把结构化对象转化为字节流②反序列化 (Deserialization) 是序列化的逆过程. 把字节流转为结构化 ...