博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据结构之线性表之ArrayList源码学习
阅读量:3940 次
发布时间:2019-05-24

本文共 3023 字,大约阅读时间需要 10 分钟。

好久没写博客,一直是写在笔记上面。

我一直用的JDK8,所以今天的源码分析也是基于JDK8。

 

ArrayList简介

 

ArrayList 是一个动态数组队列。与Java中的数组相比,它的容量能动态增长。它继承于AbstractList,实现了List, RandomAccess, Cloneable, java.io.Serializable这些接口。

 

 

ArrayList 的爸爸是AbstractList,实现了List。AbstractList 提供了相关的添加、删除、修改、遍历等功能。

ArrayList 实现了RandmoAccess接口,支持快速随机访问。
ArrayList 实现了Cloneable接口,即覆盖了函数clone(),能被克隆。
ArrayList 实现java.io.Serializable接口,这意味着ArrayList支持序列化,能通过序列化去传输。

和Vector不同,ArrayList中的操作不是线程安全的!所以,建议在单线程中才使用ArrayList,而在多线程中可以选择Vector或者CopyOnWriteArrayList。

 

ArrayList的属性

  1. 序列化id
  2. 默认初始的容量
  3. 数组长度

  4. .........

public class ArrayList
extends AbstractList
implements List
, RandomAccess, Cloneable, Serializable { // 序列化id private static final long serialVersionUID = 8683452581122892189L; // 初始的容量(这里和Android Java不一样,Android是12) private static final int DEFAULT_CAPACITY = 10; // 一个空对象 private static final Object[] EMPTY_ELEMENTDATA = new Object[0]; // 一个空对象,如果使用默认构造函数创建,则默认对象内容默认是该值 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = new Object[0]; // 当前数据对象存放地方,当前对象不参与序列化 transient Object[] elementData; // 当前数组长度 private int size; // 数组最大长度 private static final int MAX_ARRAY_SIZE = 2147483639; }

ArrayList构造函数

 

  • 默认构造函数

 

public ArrayList() {        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;    }//当进行第一次add的时候,elementData将会变成默认的增量长度:10.
  • int类型参数构造函数

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);        }    }
  • Collection类型的参数构造函数

public ArrayList(Collection
c) { //将collection对象转换成数组,然后将数组的地址的赋给elementData。        elementData = c.toArray(); //如果它的长度不为0,进而判断它是否为Object类型的数组,如果不是的话,给它copyOf()为一个Object类型的数组。否则,给它置空。        if ((size = elementData.length) != 0) {                      if (elementData.getClass() != Object[].class)                elementData = Arrays.copyOf(elementData, size, Object[].class);        } else {            // replace with empty array.            this.elementData = EMPTY_ELEMENTDATA;        }    }

ArrayList的方法

 

插入数据:add()方法

 

add方法:

  1. 确保数组已使用长度(size)加1之后的容量足够保存下一个数据
  2. 修改次数modCount 标识自增1,如果当前数组已使用长度(size)加1后的大于当前的数组长度,则调用grow方法,增长数组,grow方法会将当前数组的长度变为原来容量的1.5倍。
  3. 确保新增的数据有地方存储之后,则将新元素添加到位于size的位置上。
  4. 返回添加成功布尔值。

指定位置插入数据:add(int index, E element)方法

 

 

 

在指定位置添加元素:首先rangeCheckForAdd(index)判断索引是否超出数组下标,之后检测是否需要扩容,使用System.arraycopy 将需要插入的位置(index)后面的元素统统往后移动一位。将新的数据内容存放到数组的指定位置(index)上。

 

 

get方法:返回指定位置上的元素

 

 

 

set方法:更改指定位置的元素,并且返回旧元素

 

contains方法:调用indexOf方法,遍历数组中的每一个元素作对比,如果找到对于的元素,则返回true,没有找到则返回false。

 

 

remove方法:有两个,(1)根据索引移除元素;(2)根据对象移除元素

 

根据索引remove

 

索引没有越界时,操作数++,将指定位置(index)上的元素都往前移动一位,将最后面的一个元素置空,好让垃圾回收器回收,并且将原来的值oldValue返回

 

根据对象remove

 

 

循环遍历所有对象,得到对象所在索引位置,然后调用fastRemove方法,执行remove操作

 

clear方法:数组内的元素都置空,不减小数组容量。

 

 

 

trimToSize方法:将elementData的数组设置为ArrayList实际的容量,动态增长的多余容量被删除

 

 

 

转载地址:http://vinwi.baihongyu.com/

你可能感兴趣的文章
细品 - 逻辑回归(LR)*
查看>>
hive: size与spilt连用
查看>>
Python:ModuleNotFoundError: No module named 模块名 错误及解决方案
查看>>
Python中os与sys两模块的区别
查看>>
nohup详解
查看>>
idea .gitignore对.idea不起作用解决
查看>>
深度学习中的注意力机制(2017版)-易理解
查看>>
Transformer解析-易理解
查看>>
多维数组[:,0]和[:0:1]获取的区别
查看>>
复原Ip地址
查看>>
重建二叉树
查看>>
二叉树根节点到叶子节点的路径数字之和
查看>>
根节点到叶子节点的节点值之和等于 sum的路径
查看>>
判断二叉树是否有从根节点到叶子节点的节点值之和等于sum的路径
查看>>
反转字符串
查看>>
环形链表
查看>>
删除链表的倒数第N个节点
查看>>
回文链表
查看>>
容器盛水问题
查看>>
滑动窗口最大值
查看>>