java学习笔记之集合—ArrayList源码解析

时间:2021-12-30 01:48:48

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&period;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集合重难点梳理&comma;增强for注意事项和三种遍历的应用场景&comma;栈和队列特点&comma;数组和链表特点&comma;ArrayList源码解析&comma; 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. x01&period;Lab&period;StoreApp&colon; XP 停服,微软变脸

    变脸,川剧的一种表演形式,除了哄哄小孩,似乎别无用处.而川剧变脸从业者何其多也,存在时间何其长也.以如此多的从业者,如此长的时间,来进行科研,其成果一定是斐然吧.推而广之,试问天下谁能敌! 微软变脸, ...

  2. 网站接入QQ登录的两种方法

    第一种使用系统自带按钮登录,但是这样会弹出新窗口,不喜欢 //调用QC.Login方法,指定btnId参数将按钮绑定在容器节点中 QC.Login({ //btnId:插入按钮的节点id,必选 btn ...

  3. iOS开发之组件化架构漫谈

    前段时间公司项目打算重构,准确来说应该是按之前的产品逻辑重写一个项目.在重构项目之前涉及到架构选型的问题,我和组里小伙伴一起研究了一下组件化架构,打算将项目重构为组件化架构.当然不是直接拿来照搬,还是 ...

  4. IOS开发关于测试的好的网址资源

    1. 高级自动化单元测试,推荐看LeanCloud 工程师的李智维的自动化单元测试的直播录影李智维的演示github 2.iOS开发-单元测试 这只是一篇简单的ios测试介绍 3.iOS单元测试 来自 ...

  5. &lbrack;Javascript&rsqb; Using console&period;count to Count Events

    Learn how to user console.count in order to log out how many times a given thing has happened. ; i & ...

  6. &lbrack;转&rsqb; 详细整理:UITableView优化技巧

      原文:http://www.cocoachina.com/ios/20150602/11968.html   最近在微博上看到一个很好的开源项目VVeboTableViewDemo,是关于如何优化 ...

  7. HDU 1008 u Calculate e

    Problem Description A simple mathematical formula for e is where n is allowed to go to infinity. Thi ...

  8. Python面面面

    1:Python有哪些特点和优点? 作为一门编程入门语言,Python主要有以下特点和优点: 可解释 具有动态特性 面向对象 简明简单 开源 具有强大的社区支持 当然,实际上Python的优点远不止如 ...

  9. IDEL中easyui使用jstl和el出现传值不显示的问题

    <%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding=& ...

  10. 使用hashlib进行文件校验

    import hashlib import os path = r'D:\CentOS 64 位' def file_md5(path): """ 文件校验 :param ...