什么是ArrayList?
ArrayList是为了替代数组而进行封装的对象,依据数组的业务操作都能通过ArrayList很简洁的实现
ArrayList优缺点
因为ArrayList底层使用数组实现,所以优缺点与数组类似。
优点:
1、根据下标遍历元素效率较高。
2、根据下标访问元素效率较高。
3、在数组的基础上封装了对元素操作的方法。
4、可以自动扩容。
缺点:
1、插入和删除的效率比较低。
2、根据内容查找元素的效率较低
对比数组的优势
1.数组容量固定,ArrayList内部管理扩容,方便使用
2.ArrayList内部封装了数组的应用业务,能够更方便的是实现数组能实现的业务
ArrayList的父类与接口
RandomAccess/随机访问 的作用?
实现了此接口的 List,使用for循环的方式获取数据的效率会优于用迭代器【Iterable】获取数据(详细解释)
ArrayList的成员变量
MAX_ARRAY_SIZE为什么是int的最大减去8?
数组类型是由jvm从元素类型合成出来的,需要有字段记录对象头信息,这个8消耗在这个地方【参考解释1,参考解释2】
elementData是干嘛的?
elementData是一个Object类型的数组,通过 初始化 或者 添加 的list数据都会存放在这个数组中
DEFAULTCAPACITY_EMPTY_ELEMENTDATA 与 EMPTY_ELEMENTDATA 的作用容易混淆,到底是干嘛的?
DEFAULTCAPACITY_EMPTY_ELEMENTDATA 是用于通过默认构造器创建ArrayList对象赋值用的
EMPTY_ELEMENTDATA 也用于构造器默认赋值
但它还包括业务操作用清空elementData数据的逻辑操作赋值,例如:
通过上面的内容可以对他们打标签进行区分:
1.默认为空数组赋值
2.业务为空数组赋值
这就延申出另外一个问题,为什么ArrayList需要这两种不同的空数组赋值?
待研究
ArrayList的成员方法
ArrayList是怎样动态扩容的?
DEFAULTCAPACITY_EMPTY_ELEMENTDATA 扩容与 EMPTY_ELEMENTDATA 的扩容机制并不相同,具体通过
calculateCapacity方法控制
DEFAULTCAPACITY_EMPTY_ELEMENTDATA的扩容顺序是 第一次扩容大小为10,超过当前size每次扩容当前size的1.5倍
EMPTY_ELEMENTDATA的扩容顺序是 每次扩容当前size的1.5倍,若size的1.5倍等于等前size的大小,则扩容大小为当前的size+1
【即传参minCapacity,在add方法调用:ensureCapacityInternal(size + 1)】
扩容逻辑源码如下:
关于位运算提示:
机器并不能直接识别阿拉伯数字和字母,只能进行简单的判断是成功还是失败,
通过这个因素科学家将其转意为“成功代表1,失败代表0”,
于是机器就能创建“000000000”“11111111”“010101010011”这样的位码,
但仅这个样子人类还是无法使用机器进行简单计算,
于是在此基础上再次赋意建立了进制概念,什么二进制,十进制等等
而赋意运算规则是
即 从左往右每一位都是后一位的一倍,所以最简单的就叫 二进制
十进制的基础是二进制,并不是位码
错误示例 从右往左 ..... 100 10 1
正确示例 十进制转换成二进制【数字10】为
转二进制 1 0 1 0
赋意 8 4 2 1
即 位码为1部分相加为 10
机器能够根据二进制计算,但操作系统一般都是十进制,故需要转换成二进制
而位运算 >> 的意思是当前位码向左移动一位,即最后一位(最右)删掉,前面(最左)补一位0
例如 10 >> 1 的运算步骤如下
1.转换为二进制
二进制 1010
2.移动位
二进制 0101
3.转换为十进制,结果为5
即为当前数量的一半
看到这里,ArrayList的源码基础部分应该都能看懂,什么 remove,add,get等等方法就不细说的,阅读源码的快乐还需要各位自己来获取,下面讲讲ArrayList的进阶知识
迭代器【Iterable】
网上都有详细的说明迭代使用不当造成的问题,这里不再赘述
拆分迭代器【Spliterator 】
后续复习继续补充