数据结构之线性表之ArrayList源码学习

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

我一直用的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<E> extends AbstractList<E> implements List<E>, 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<? extends E> 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实际的容量,动态增长的多余容量被删除

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值