Java源码阅读------ArrayList(1)

本文主要探讨了Java中ArrayList的基本操作,包括初始化、按索引取值与赋值、按值查找、容量扩充与裁剪、插入和移除数据。通过分析源码,解释了ArrayList如何实现动态存储和自动扩容,并提供了相关操作的详细步骤。
摘要由CSDN通过智能技术生成

简介

java中的线性表容器,是一种顺序表的结构,核心是用一个数组来对数据进行存储,同时也是一个容器,可以实现数据的动态存储。ArrayList中使用了泛型的定义,所以在实际的存储中存储的对象不能是基本类型(int,double等)。

基本操作

先从一些基本设计来看:

    transient Object[] elementData;//实际用于存储的数组
	private static final int DEFAULT_CAPACITY = 10;//默认的容器容量
	private int size;//实际的数量

这里有一个区分一个是数据的数量,表述已经装入了这么多数量的数据,一个是容器的容量表示目前开辟的内存空间可以装这么多的数据。既然是一个顺序表的结构我们再看看其基本的操作。

初始化(构造函数)

这个类提供了三个构造函数。
默认生成空的线性表:

public ArrayList() {
   
	this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

这里的空的表是初始化时将表置空,还有一个空表是在之后操作时表中没有数据了,为了区分这两个逻辑使用了两个引用加以区分。

private static final Object[] EMPTY_ELEMENTDATA = {
   };//空的表

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {
   };
//初始化时的空表,这时的容器容量为默认容量。

自定义容器大小的初始化,在初始化的时候不使用默认的容量初始化数组:

public ArrayList(int initialCapacity) {
   
	if (initialCapacity > 0) {
   //判断传入的大小是否合法
    	this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {
   //如果是0就是建立空表
        this.elementData = EMPTY_ELEMENTDATA;
    } else {
   //异常处理
        throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
	}
}

最后一个构造函数是以一个原有容器中的数据为基础创建顺序表:

public ArrayList(Collection<? extends E> c) {
   
	elementData = c.toArray();//类型转换
    if ((size = elementData.length) != 0) {
   
        if (elementData.getClass() != Object[].class)
        	//转换之后的类型可能不是Object数组,再使用Arrays.copyOf()方法转化。
            elementData = Arrays.copyOf(elementData, size, Object[].class);
    } else {
   //如果传入的是个空的容器就设置一个空表
        this.elementData = EMPTY_ELEMENTDATA;
	}
}

Collection这个接口为所有容器提供了一些共有的操作定义

ArrayList实现了List接口,而Collection是所有相关容器接口的父接口。
所以使用Collection可以代指所有与容器相关的类。
toArray方法是Collection接口中定义的,可以将相关的数据转换为数组。当然ArrayList也实现了这个方法。但是实际的实现对象是Arrays类。

public Object[] toArray() {
   
	return Arrays.copyOf(elementData, size);
}

再到Arrays中看看:

//保持默认类型的转换
public static <T> T[] copyOf(T[] original, int newLength) {
   
	return (T[]) copyOf(original, newLength, original.getClass());
}

//指定类型的转换
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
   
	@SuppressWarnings("unchecked")
	//根据出传入的类型和大小size来初始化一个数组
	//如果不是Object类型就获取其默认类型(反射),并完成数组的空间开辟
    T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值