ArrayList源码分析

ArrayList详解
本文深入解析ArrayList的构造函数、添加、删除操作及内部扩容机制,强调合理预设容量的重要性,避免内存浪费,提升使用效率。

构造函数(有参和无参):

无参:有个被transient关键字修饰的elementData的Object类型长度为0的数组。

有参:参数的含义就是这个集合的含量,在ArrayList中如果指定了长度的话,会让元素容易指向一个新的Object数组,长度为转入的值,如果转入的长度为0,那么就默认使用Object类型长度为0的DEFAULTCAPACITY_EMPTY_ELEMENTDATA数组。

 

添加Add方法(对Object[]的elementData属性的操作):

 

 

如果我们一开始声明的是一个空参的构造函数,那么代码会走进第一个if语句,传入的minCapacity是1,那么最终计算得出minCapacity是等于10的也就是说,如果我们添加了一个默认的无参构造函数,在添加时,数组会将默认的数组长度变为10。

 

集合初始化的优化思路:

如果我们很确定的知道我们要存储元素的数量,最好在声明集合的时候传入容量值。试想,如果我们只需要存储3个元素,而我们声明了一个空参的构造函数,那么集合的长度会是10,也就是说,数组有7个长度的空间被浪费了,这就是对内存的一种浪费。

 

 

ArrayList的扩容(对Object[]的elementData属性的操作)::

声明数组长度之后会判断数组的容量是否够用,如果够用,那么不需要扩容,反之,则进行扩容,判断扩容代码没什么,很简单,但是扩容怎么办呢?数组一旦声明不是不能更改了吗?源码中是用Arrays的copyOf方法,将数组进行copy,而copyOf的底层源码,是声明了一个新的数组,然后将原有的数组内容全复制进去,这样,就在不影响原有数据的基础上进行了数组扩容。

注:在扩容过程中,如果超出了JDK对ArrayList的指定长度则会抛出数组越界异常。

 

集合扩容的优化思路:

我们需要保存1000个元素,而一开始默认长度是10,那么集合需要很多次扩容,每次扩容是上一次容量的1.5倍,每次扩容还要进行复制。如果不事先声明一个长度的话,使用效率会大大降低,即便是不知道具体数字,也可以指定一个大概的容量。

 

删除remove(对Object[]的elementData属性的操作):

 

删除是每次进行数组复制,然后让旧的elementData置为null进行垃圾回收,elementData[(--size)] 就是将ArrayList最后一个长度因为删除了元素向前移了,然后通过垃圾回收机制将其置为空。

 

 

ArrayList的使用总结

1.在声明时尽量指定长度。

2.ArrayList底层是数组(Object [] elementData),数组是适合查询的,因为数组每个元素的内存空间是固定的,每次查询时,只需要去查询对应位置的内存空间,就可以很快找到相应的值。而数组不擅长的是添加和删除(使用LinkedList)。

3.在开发过程中如果想让ArrayList/LinkedList变成线程安全的就需要使用Collections.synchronizedList(new ArrayList())方法会返回一个线程安全的ArrayList集合。

List<String> list = Collections.synchronizedList(new ArrayList<String>());

4.借助Collections--此类仅包含对集合进行操作或返回集合的静态方法。它包含对集合进行操作的多态算法,“包装器”,它返回由指定集合支持的新集合,以及其他一些可能性和结束。如果提供给它们的集合或类对象为null ,则此类的方法都抛出NullPointerException。

 

 

ArrayList使用的transient的使用总结

1)一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。

2)transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。

3)被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

、小H

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值