1、ArrayList简介

ArrayList是一个数组队列,与java中的数组的容量固定不同,它可以动态的实现容量的增涨。所以ArrayList也叫动态数组。当我们知道有多少个数据元素的时候,我们用传统数组就可以解决问题,可当我们不知道有多少个数据元素的时候我们就可以用ArrayList。

2、继承关系

public class ArrayList<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable

它继承于AbstractList,实现了List, RandomAccess, Cloneable, java.io.Serializable这些接口。

ArrayList 继承了AbstractList实现了List。它是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。
ArrayList 实现了RandmoAccess接口,即提供了随机访问功能RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在ArrayList中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。稍后,我们会比较List的“快速随机访问”和“通过Iterator迭代器访问”的效率。

ArrayList 实现了Cloneable接口,即覆盖了函数clone(),能被克隆。

ArrayList 实现java.io.Serializable接口,这意味着ArrayList支持序列化,能通过序列化去传输。

3、实现原理

transient Object[] elementData;

ArrayList的底层就是一个对象数组,ArrayList类就是对该数组的封装。除了对象数组elementData之外,ArrayList中还定义了空数组(EMPTY_ELEMENTDATA),和默认空数组(DEFAULTCAPACITY_EMPTY_ELEMENTDATA) 。

private static final Object[] EMPTY_ELEMENTDATA = {};
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

这两个数组的作用体现在接下来要介绍的ArrayList的构造方法之中。

4、构造方法

无参构造方法

/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
} /**

无参构造方法中,将 DEFAULTCAPACITY_EMPTY_ELEMENTDATA数组赋给elementData,这样一来,elementData就是一个空数组。

有参构造方法

import java.util.ArrayList;
/**
*
* @author asus
* 使用给默认长度的方法创建ArrayList对象
*/
public class ArrayListDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<String> al = new ArrayList<String>(3);
al.add("666");
}
}

我们看一下这种构造方法的源码

//capacity是ArrayList的默认容量大小。当由于增加数据导致容量不足时则会采用2倍的形式进行容
量的扩充
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}

构造了一个指定大小但内容为空的数组,initialCapacity参数就是初始容量大小。

5、ArrayList如何实现容量动态增长

以ArrayList中的add()方法为例,当ArrayList中增加一个数据元素时,意味着ArrayList的容量至少要加1(elementData.length+1),calculateCapacity()将elementData.length+1与默认初始容量DEFAULT_CAPACITY = 10 进行对比,并返回其中更大的数作为最小容量长度 (minCapacity)。再调用方法grow(),将minCapability与ArrayList的容量的2倍(elementData.length + (elementData.length >> 1))进行比较并选择其中更大的数作为ArrayList新的容量newCapability,然后在通过elementData = Arrays.copyOf(elementData, newCapacity);将新的数组赋给elementData。这样一来,ArrayList就成功的完成了数组长度的动态增长。

我们看一下这一过程的源码:

public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
} private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
} private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
} private void ensureExplicitCapacity(int minCapacity) {
modCount++; // overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
} //将至少需要的容量与原容量的2倍进行比较,确定新的容量
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
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);
}

java学习笔记之集合—ArrayList源码解析的更多相关文章

  1. Java入门系列之集合ArrayList源码分析(七)

    前言 上一节我们通过排队类实现了类似ArrayList基本功能,当然还有很多欠缺考虑,只是为了我们学习集合而准备来着,本节我们来看看ArrayList源码中对于常用操作方法是如何进行的,请往下看. A ...

  2. Java集合-ArrayList源码解析-JDK1.8

    ◆ ArrayList简介 ◆ ArrayList 是一个数组队列,相当于 动态数组.与Java中的数组相比,它的容量能动态增长.它继承于AbstractList,实现了List, RandomAcc ...

  3. 集合-ArrayList 源码解析

    ArrayList是一种以数组实现的List,与数组相比,它具有动态扩展的能力,因此也可称之为动态数组. 类图 ArrayList实现了List, RandomAccess, Cloneable, j ...

  4. Java中的容器(集合)之ArrayList源码解析

    1.ArrayList源码解析 源码解析: 如下源码来自JDK8(如需查看ArrayList扩容源码解析请跳转至<Java中的容器(集合)>第十条):. package java.util ...

  5. Java学习笔记之---集合

    Java学习笔记之---集合 (一)集合框架的体系结构 (二)List(列表) (1)特性 1.List中的元素是有序并且可以重复的,成为序列 2.List可以精确的控制每个元素的插入位置,并且可以删 ...

  6. Collection集合重难点梳理,增强for注意事项和三种遍历的应用场景,栈和队列特点,数组和链表特点,ArrayList源码解析, LinkedList-源码解析

    重难点梳理 使用到的新单词: 1.collection[kəˈlekʃn] 聚集 2.empty[ˈempti] 空的 3.clear[klɪə(r)] 清除 4.iterator 迭代器 学习目标: ...

  7. java提高(8)---ArrayList源码

    ArrayList源码 一.定义 public class ArrayList<E> extends AbstractList<E> implements List<E& ...

  8. 顺序线性表 ---- ArrayList 源码解析及实现原理分析

    原创播客,如需转载请注明出处.原文地址:http://www.cnblogs.com/crawl/p/7738888.html ------------------------------------ ...

  9. 面试必备:ArrayList源码解析(JDK8)

    面试必备:ArrayList源码解析(JDK8) https://blog.csdn.net/zxt0601/article/details/77281231 概述很久没有写博客了,准确的说17年以来 ...

随机推荐

  1. Linux 报错:syntax error "C" 解决办法(此处选择bash系统)

    出现此问题的原因,是由系统的兼容性引起的,linux下默认了指向dash而非bash. linux下Dash改Bash: 1.先查看是使用哪个shell ls -al /bin/sh 2.#如果是Da ...

  2. Jenkins自动化构建vue项目然后发布到远程Linux服务器

    部署Jenkins参照另一篇博客: centos7安装Jenkins及其卸载 一.jenkins相关插件的安装 1.安装Publish Over SSH插件用于SSH连接远程的服务器. 登录 jenk ...

  3. np.vstack与np.hstack

    转自:https://zhuanlan.zhihu.com/p/82996332   留作备忘

  4. A——大整数加法(HDU1002)

    题目: I have a very simple problem for you. Given two integers A and B, your job is to calculate the S ...

  5. pip 安装源-Python学习

    1.国内常用的安装源 -- 豆瓣:https://pypi.douban.com/simple -- 阿里:https://mirrors.aliyun.com/pypi/simple --中国科技大 ...

  6. JS循环解决任意日期间的间隔天数

    用JS循环解决任意日期间的间隔天数,并求截止日期是周几 y1=1900 m1=1 d1=1 y2=2000 m2=5 d2=3 days=0 ydays=0 mdays=0 ddays=d2-d1 f ...

  7. Java日志介绍(4)-Log4j2

    Log4j2是Log4j的升级版,相比其前身Log4j 1.x提供了显著的改进,并提供了在Logback中提供的许多改进,同时修复了Logback体系结构中的一些固有问题. Log4j2的内容很多,本 ...

  8. C#实现的一些常见时间格式

    string aa = DateTime.Now.ToShortDateString();//"2019/9/23" string bb = DateTime.Now.ToShor ...

  9. Android应用第一次启动时的欢迎界面制作

    原理是这样,我们在SharedPreferences中存储一个int型数据,用来代表第几次登录,每次启动时都读取出来判断是不是第一次启动,然后依次判断是否要显示欢迎界面, 具体实现如下: 设置一个欢迎 ...

  10. 185.nvm和node.js环境配置

    安装nvm nvm(Node Version Manager)是一个用来管理node版本的工具,我们之所以使用node,是因为我们需要使用node中的npm(Node Package Manager) ...