1. 底层数据结构
ArrayList是List接口的可调整大小的数组实现
增删慢:每次增删数据,需要拷贝以及移动元素位置
查询快:数组内存是一块连续空间,可以根据索引方式获取对应位置元素
2. 实现与继承
2.1 Serializable接口
序列化接口,没有方法或字段,仅用于标识,实现该接口才能实现序列化反序列化
序列化:将对象的数据转换成字节序列写入文件
反序列化:将文件中的字节序列数据恢复出来
序列版本号:
序列版本号是序列化前后唯一标识符号
如果没有人为指定序列版本号,编译器会自动添加
反序列化时,JVM会把字节流中的序列版本号与被序列化类中的序列版本号进行比对,一致才会进行反序列化,否则报错
建议实现该接口后人为写序列版本号(或自动添加)
static修饰部分不会被序列化:因为序列化保存的是对象的状态,与类无关
transient修饰部分不会被序列化:希望某些字段不被序列化(如密码),该字段反序列化结果为null
2.2 Cloneable接口
克隆接口
被克隆对象的类必须实现克隆接口
重写clone方法
浅拷贝通过重写clone方法实现
深拷贝推荐使用序列化方式实现
2.3 RandomAccess接口
快速随机访问接口,允许算法更改其行为,以便应用于随机访问列表或顺序访问列表时提供良好的性能
实现了该接口的List,则使用普通for循环随机访问,ArrayList
没有实现该接口的List,则使用增强for循环或迭代器进行顺序访问,LinkedList
2.4 AbstractList抽象类
List接口的骨架实现,ArrayList,LinkedList都是其子类
3. 源码分析
3.1 构造方法
ArrayList():构造初始容量为10的空列表
ArrayList(Collection extends E> c):构造一个包含指定集合元素的列表,按照他们由集合的迭代器返回的顺序
ArrayList(int initialCapacity):构造具有指定初始容量的空列表
3.2 添加方法
public boolean add(E, e):指定元素添加到列表末尾
扩容:扩容为原来的1.5倍
public void add(int index, E, element):指定位置添加元素
指定位置添加:指定位置后元素先后移,指定位置再添加元素
public boolean addAll(Collection extends E> c):c中元素追加到列表末尾,按照c迭代器返回顺序添加
public boolean addAll(int index, Collection extends E> c):c中元素添加到指定位置
3.3 迭代器
public Iterator iterator():以正确顺序返回该列表中元素的迭代器
集合的迭代器接口public interface Iterator
方法说明
default void forEachRemaining(Consumer super E> action)
对每个元素进行某种操作
boolean hasNext()
E next()
default void remove()
从集合中删除此迭代器返回的最后一个元素
补充:
可迭代接口public interface Iterable,实现了该接口的对象可以使用增强for循环
方法说明
default void forEach(Consumer super T> action)
对每个元素执行操作
Iterator iterator()
返回T元素的迭代器
3.4 其他方法
略
4. 常见面试题
4.1 如何扩容
构建新数组,新数组大小为原数组的1.5倍,原数组元素复制进入新数组
4.2 频繁扩容导致添加性能急剧下降,如何解决
通过指定初始容量初始化数组
4.3 插入删除元素一定慢吗
取决于元素离数组末端距离,不一定每次插入都需要构建新数组,因此不一定比LinkedList慢
4.4 线程安全问题
ArrayList非线程安全,线程安全版本为Vector.
4.5 和LInkedList区别
问:ArrayList,LinkedList哪个更占空间?
答:
表面上LInkedList更占空间(包括前索引,后索引)
实际上如果ArrayList添加元素超过数组大小时,需要扩容为1.5倍,如果只添加一个元素则会有较大的空间浪费,因此ArrayList不一定比LinkedList节省空间.
ArrayList中elementData表示底层数组,默认10,用transient修饰,size表示数组中元素个数.ArrayList重写了writeObject方法,序列化时候不会把elementData数组完全序列化,只序列化elementData中的前size个元素,空值不会序列化.
2. 实现与继承
2.1 Serializable接口
序列化接口,没有方法或字段,仅用于标识,实现该接口才能实现序列化反序列化
序列化:将对象的数据转换成字节序列写入文件
反序列化:将文件中的字节序列数据恢复出来
序列版本号:
序列版本号是序列化前后唯一标识符号
如果没有人为指定序列版本号,编译器会自动添加
反序列化时,JVM会把字节流中的序列版本号与被序列化类中的序列版本号进行比对,一致才会进行反序列化,否则报错
建议实现该接口后人为写序列版本号(或自动添加)
static修饰部分不会被序列化:因为序列化保存的是对象的状态,与类无关
transient修饰部分不会被序列化:希望某些字段不被序列化(如密码),该字段反序列化结果为null
2.2 Cloneable接口
克隆接口
被克隆对象的类必须实现克隆接口
重写clone方法
浅拷贝通过重写clone方法实现
深拷贝推荐使用序列化方式实现
2.3 RandomAccess接口
快速随机访问接口,允许算法更改其行为,以便应用于随机访问列表或顺序访问列表时提供良好的性能
实现了该接口的List,则使用普通for循环随机访问,ArrayList
没有实现该接口的List,则使用增强for循环或迭代器进行顺序访问,LinkedList
2.4 AbstractList抽象类
List接口的骨架实现,ArrayList,LinkedList都是其子类
3. 源码分析
3.1 构造方法
ArrayList():构造初始容量为10的空列表
ArrayList(Collection extends E> c):构造一个包含指定集合元素的列表,按照他们由集合的迭代器返回的顺序
ArrayList(int initialCapacity):构造具有指定初始容量的空列表
3.2 添加方法
public boolean add(E, e):指定元素添加到列表末尾
扩容:扩容为原来的1.5倍
public void add(int index, E, element):指定位置添加元素
指定位置添加:指定位置后元素先后移,指定位置再添加元素
public boolean addAll(Collection extends E> c):c中元素追加到列表末尾,按照c迭代器返回顺序添加
public boolean addAll(int index, Collection extends E> c):c中元素添加到指定位置
3.3 迭代器
public Iteratoriterator():以正确顺序返回该列表中元素的迭代器
集合的迭代器接口public interface Iterator
方法
说明
default void forEachRemaining(Consumer super E> action)
对每个元素进行某种操作
boolean hasNext()
E next()
default void remove()
从集合中删除此迭代器返回的最后一个元素
补充:
可迭代接口public interface Iterable,实现了该接口的对象可以使用增强for循环
方法
说明
default void forEach(Consumer super T> action)
对每个元素执行操作
Iteratoriterator()
返回T元素的迭代器
3.4 其他方法
略
4. 常见面试题
4.1 如何扩容
构建新数组,新数组大小为原数组的1.5倍,原数组元素复制进入新数组
4.2 频繁扩容导致添加性能急剧下降,如何解决
通过指定初始容量初始化数组
4.3 插入删除元素一定慢吗
取决于元素离数组末端距离,不一定每次插入都需要构建新数组,因此不一定比LinkedList慢
4.4 线程安全问题
ArrayList非线程安全,线程安全版本为Vector.
4.5 和LInkedList区别
问:ArrayList,LinkedList哪个更占空间?
答:
表面上LinkedList更占空间(包括前索引,后索引)
实际上如果ArrayList添加元素超过数组大小时,需要扩容为1.5倍,如果只添加一个元素则会有较大的空间浪费,因此ArrayList不一定比LinkedList节省空间.
ArrayList中elementData表示底层数组,默认10,用transient修饰,size表示数组中元素个数.ArrayList重写了writeObject方法,序列化时候不会把elementData数组完全序列化,只序列化elementData中的前size个元素,空值不会序列化.
4.6 如何复制一个ArrayList到另一个ArrayList
clone()方法
ArrayList构造方法
addAll方法-p">
4.6 如何复制一个ArrayList到另一个ArrayList
clone()方法
ArrayList构造方法
addAll方法
标签:java,迭代,part01,ArrayList,元素,接口,数组,序列化
来源: https://www.cnblogs.com/OLeeO97/p/14208582.html