在端午节这个节日里,有一个特殊的任务,我带着你一起揭开“ArrayList”的真面目。从成员变量、构造函数、主要方法三部分,对ArrayList有进一步的认识,希望能够帮助你。

一、成员变量

   //默认容量
private static final int DEFAULT_CAPACITY = 10;
//空数组,当调用无参数构造函数的时候默认给个空数组
private static final Object[] EMPTY_ELEMENTDATA = {};
//真正保存数据的数组
private transient Object[] elementData;
//数组的大小
private int size;

transient关键字:ArrayList实现了Serializable接口,而添加上transient关键字,则elementData对象就不可以序列化。

二、构造函数

  • 无参构造方法

  • 带有容量的构造方法

  • 带参数Collection的构造方法

在参数Collection的构造方法中,只有当当得到的elementData的类名不是Object,才会执行复制操作,因为Java是动态绑定,所以getClass获取的并不一定是Object类型,有可能是它的子类。

/**
* 初始化elementData
* @param initialCapacity
*/
public ArrayList(int initialCapacity) {
super();
//如果小于0,则抛出异常
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
//初始化elementData数组
this.elementData = new Object[initialCapacity];
} /**
* 初始化为空的对象数组
*/
public ArrayList() {
super();
this.elementData = EMPTY_ELEMENTDATA;
} public ArrayList(Collection<? extends E> c) {
//将c容器转换为object类型的数组
elementData = c.toArray();
//更新size的大小
size = elementData.length;
//当得到的elementData的类名不是Object,才会执行复制操作
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}

三、主要方法

1、add方法

//添加元素
public boolean add(E e) {
//首先判断数组容量是否需要扩充
ensureCapacityInternal(size + 1); // Increments modCount!!
//添加元素,更新size的大小
elementData[size++] = e;
return true;
}

ArrayList相当于在没指定initialCapacity时就是会使用延迟分配对象数组空间,当第一次插入元素时ensureCapacityInternal,才分配10个对象空间。

2、get方法

 //通过下标获取元素
public E get(int index) {
//判断下标的合理性
rangeCheck(index);
//返回元素
return elementData(index);
}

3、remove方法

在remove方法中,我们需要注意对null的特殊处理。

public boolean remove(Object o) {
//如果为null对象,则特殊处理,使用==来判断
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
//如果不为null,则使用equals方法来判断。
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}

四、其他常用的方法

removeAll:移除集合A和集合B的交集,即A-B。

retainAll:保留两个集合的交集。

五、ArrayList的大小是如何自动增加的?(面试题)

  • ensureCapacityInternal    是判断是否要扩容的方法

  • ensureExplicitCapacity

  • grow 具体的扩容方法

实现思想:

  1. 确定所需minCapacity和数组当前size的关系,如果minCapacity>size,则准备grow。

  2. 如果1.5size<minCapacity,则准备扩充为minCapacity。

  3. minCapacity和MAX_ARRAY_SIZE 的关系,如果minCapacity>MAX_ARRAY_SIZE ,则需要判断minCapacity是否超出int类型所能表示的最大值。如果超出,则抛出OutOfMemoryError。

 //确保数组能够存放的:minCapacity
private void ensureCapacityInternal(int minCapacity) {
//如果elementData是空对象数组,最小容量为minCapacity和DEFAULT_CAPACITY最大值
if (elementData == EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
//判断是否需要扩容
ensureExplicitCapacity(minCapacity);
} private void ensureExplicitCapacity(int minCapacity) {
//增加被改变的次数
modCount++;
// 最小容量大于elementData的长度,则需要扩充
if (minCapacity - elementData.length > 0)
grow(minCapacity);
} //数组的最大上限
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; private void grow(int minCapacity) {
// 数组原来的长度,保存副本
int oldCapacity = elementData.length;
//扩容至原来的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
//判断新容量是否够用,如果不够则赋值为minCapacity
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//如果newCapacity超过MAX_ARRAY_SIZE
if (newCapacity - MAX_ARRAY_SIZE > 0)
//检查容量的int值是不是已经溢出。
newCapacity = hugeCapacity(minCapacity);
// 调用Arrays.copyOf方法将elementData数组指向新的内存空间时newCapacity的连续空间
// 并将elementData的数据复制到新的内存空间
elementData = Arrays.copyOf(elementData, newCapacity);
} private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}

欢迎加入Java学习交流群点击:484757838 

ArrayList源码解读的更多相关文章

  1. ArrayList 源码解读

    ArrayList 源码解读     基于JDk 1.7.0_80 public class ArrayList<E> extends AbstractList<E> impl ...

  2. JDK12下的ArrayList源码解读 与 Vector的对比

    ArrayList源码阅读. //测试代码实现如下 private static void arrayList() { ArrayList<String> list = new Array ...

  3. ArrayList源码解读(jdk1.8)

    概要 上一章,我们学习了Collection的架构.这一章开始,我们对Collection的具体实现类进行讲解:首先,讲解List,而List中ArrayList又最为常用.因此,本章我们讲解Arra ...

  4. 深入理解JAVA集合系列四:ArrayList源码解读

    在开始本章内容之前,这里先简单介绍下List的相关内容. List的简单介绍 有序的collection,用户可以对列表中每个元素的插入位置进行精确的控制.用户可以根据元素的整数索引(在列表中的位置) ...

  5. Java集合ArrayList源码解读

    最近在回顾数据结构,想到JDK这样好的代码资源不利用有点可惜,这是第一篇,花了心思.篇幅有点长,希望想看的朋友认真看下去,提出宝贵的意见.  :) 内部原理 ArrayList 的3个字段 priva ...

  6. java集合之ArrayList源码解读

    源自:jdk1.8.0_121 ArrayList继承自AbstractList,实现了List.RandomAccess.Cloneable.Serializable. ArrayList内部是通过 ...

  7. ArrayList源码解读笔记

    简介: ArrayList是我们开发中非常常用的数据存储容器之一,其底层是数组实现的,我们可以在集合中存储任意类型的数据,ArrayList是线程不安全的,非常适合用于对元素进行查找,效率非常高. 线 ...

  8. Java集合(四)--基于JDK1.8的ArrayList源码解读

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

  9. jdk1.8.0_45源码解读——ArrayList的实现

    jdk1.8.0_45源码解读——ArrayList的实现 一.ArrayList概述 ArrayList是List接口的可变数组的实现.实现了所有可选列表操作,并允许包括 null 在内的所有元素. ...

随机推荐

  1. EXCEL数据导入数据库实例(NPOI)

    Default.aspx 页面代码: 引用了:    <script src="../../js/jquery.easyui.min.js" type="text/ ...

  2. DOM 以及JS中的事件

    [DOM树节点] DOM节点分为三大节点:元素节点,文本节点,属性节点. 文本节点,属性节点为元素节点的两个子节点通过getElment系列方法,可以去到元素节点 [查看节点] 1 document. ...

  3. HDU 5558 后缀数组+二分

    题意有一些绕,但其实就是对于不断变化的i,求以j(0=j<i)使得suffix[j]与suffix[i]的最长公共前缀最长,如果有多个j,则取最小的j. 可以在rank数组中二分,在1-rank ...

  4. JS模式--职责链模式

    职责链模式的定义:使用多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这些对象连成一条链, 并沿着这条链条传递下去,直到有一个对象处理它为止. var order500 = f ...

  5. [ext4]空间管理 - 与分配相关的关键数据结构

     在块分配机制中,涉及到几个主要的数据结构. 通过ext4_allocation_request描述块请求,然后基于块查找结果即上层需求来决定是否执行块分配操作. 在分配过程中,为了更好执行分配, ...

  6. [ext4]03 磁盘布局 – Flexible group分析

    Flexible Block Groups (flex_bg),我称之为"弹性块组",是EXT4文件系统引入的一个feature. 所谓Flexible Block Groups, ...

  7. 如何在 ASP.NET Core 中发送邮件

    前言 我们知道目前 .NET Core 还不支持 SMTP 协议,当我么在使用到发送邮件功能的时候,需要借助于一些第三方组件来达到目的,今天给大家介绍两款开源的邮件发送组件,它们分别是 MailKit ...

  8. 微信小程序,前端大梦想(五)

    微信小程序之综合应用-访问网络加载数据 移动端访问网络加载数据时必不可少的功能,本章将接入豆瓣电影API,以列表的形式展现数据,支持下拉刷新及点击查看详情.重点包括: l 访问网络 l 跳转画面及传参 ...

  9. AOJ/树二叉搜索树习题集

    ALDS1_7_A-RootedTree. Description: A graph G = (V, E) is a data structure where V is a finite set of ...

  10. Reactjs vs. Vuejs

    欢迎大家关注腾讯云技术社区-博客园官方主页,我们将持续在博客园为大家推荐技术精品文章哦~ 纪俊,从事Web前端开发工作,2016年加入腾讯OMG广告平台产品部,喜欢研究前端技术框架. 这里要讨论的话题 ...