ArrayList

1. ArrayList集合底层数据结构

1.1 ArrayList集合介绍

List 接口的可调整大小的数组实现。
数组 : 一旦初始化长度就不可以发生改变

1.2. 数组结构介绍

增删慢:每次删除元素,都需要更改数组长度、拷贝以及移动元素位置。
查询快:由于数组在内存中是一块连续空间,因此可以根据地址 + 索引的方式快速获取对应位置上的元素

2. ArrayList继承关系

2.1 Serializable 标记性接口
1. 介绍 类的序列化由实现 java.io.Serializable 接口的类启用。 不实现此接口的类将不会使任何状态序列化或反
序列化。 可序列化类的所有子类型都是可序列化的。 序列化接口没有方法或字段,仅用于标识可串行化的语
义。
序列化 : 将对象的数据写入到文件 ( 写对象 )
反序列化 : 将文件中对象的数据读取出来 ( 读对象 )

2.2 Cloneable 标记性接口

1. 介绍 一个类实现 Cloneable 接口来指示 Object.clone() 方法,该方法对于该类的实例进行字段的复制是合
法的。在不实现 Cloneable 接口的实例上调用对象的克隆方法会导致异常 CloneNotSupportedException 被抛
出。 简言之 : 克隆就是依据已经有的数据,创造一份新的完全一样的数据拷贝
 克隆的前提条件
被克隆对象所在的类必须实现 Cloneable 接口
必须重写 clone 方法

浅克隆和深克隆

浅克隆

存在的问题 : 基本数据类型可以达到完全复制,引用数据类型则不可以
原因 : 引用数据类型 仅仅是拷贝了一份引用,因此当 值发生改
变时,被克隆对象 也将跟随改变
深克隆
浅克隆只是Student类重写了clone方法

而深克隆Student类和Skill类都重写了clone方法,并且Student类不再是调用父类得clone方法,而是自己重写了代码

 

2.3 RandomAccess标记接口

1. 介绍 标记接口由 List 实现使用,以表明它们支持快速(通常为恒定时间)随机访问。
此接口的主要目的是允许通用算法更改其行为,以便在应用于 随机访问列表 顺序访问列表 时提供良好的性
能。

3. ArrayList源码分析

3.1 构造方法

Constructor
Constructor 描述
ArrayList()
构造一个初始容量为十的空列表。
ArrayList(int initialCapacity)
构造具有指定初始容量的空列表。
ArrayList(Collection<? extends
E> c)
构造一个包含指定集合的元素的列表,按照它们由集合的迭代器返回
的顺序。

3.2 添加方法

方法名
描述
public boolean add(E e)
将指定的元素追加到此列表的末尾。
public void add(int index, E element)
在此列表中的指定位置插入指定的元素。
public boolean addAll(Collection<?
extends E> c)
按指定集合的 Iterator 返回的顺序将指定集合中的所有元素
追加到此列表的末尾。
public boolean addAll(int index,
Collection<? extends E> c)
将指定集合中的所有元素插入到此列表中,从指定的位置
开始。

3.3 删除方法

public E remove(int index) 根据索引删除元素
//底层拷贝数组得方法
System.arraycopy(Object[] src, int srcPos, Object[] dest, int destPos, int length)
//src - 源数组。
//srcPos - 源数组中的起始位置。
//dest - 目标数组。
//destPos - 目的地数据中的起始位置。
//length - 要复制的数组元素的数量

3.4 修改方法

public E set(int index, E element) 根据索引修改集合元素

3.5 获取方法

public E get(int index) 根据索引获取元素

3.6 转换方法

public String toString() 把集合所有数据转换成字符串

3.7 清空方法

public void clear() 清空集合所有数据

3.8 包含方法

public boolean contains(Object o) 判断集合是否包含指定元素

3.9 判断集合是否为空

public boolean isEmpty()

4. 面试题

4.1 ArrayList 是如何扩容的?
无参构造初始化时,默认为10,每次扩容是原容量得1.5倍
4.2 ArrayList 频繁扩容导致添加性能急剧下降,如何处理?
对于已知要存储得数据量,直接使用带初始容量参数得构造方法
如果对于要存储的数据量不清楚,不要随意使用这个构造方法,有可能会造成数组空间利用率不高
4.3 ArrayList 插入或删除元素一定比 LinkedList 慢么 ?
不一定,不管查找还是删除,都要先找到一个位置,而ArrayList查找的速度比LinkedList快,但在插入或删除元素时(如果不需要扩容),Arraylist涉及到数组的拷贝,而(需要扩容的时候,还涉及到新数组的创建),所以ArrayList 真正插入和删除元素的速度比LinkedList慢,综上, ArrayList 插入或删除元素不一定比 LinkedList
4.4 ArrayList 是线程安全的么?
ArrayList不是线程安全的
需要线程安全怎么办 ?
方式一 : 使用 Collections.synchronizedList(list)
使用Collectons这个工具类的的synchronizedList(list)方法,将集合变成线程安全的
方式二:使用Vector代替ArrayList
4.5 如何复制某个 ArrayList 到另一个 ArrayList 中去?
使用 clone() 方法
使用 ArrayList 构造方法
使用 addAll 方法
4.6 已知成员变量集合存储 N 多用户名称 , 在多线程的环境下 , 使用迭代器在读
取集合数据的同时如何保证还可以正常的写入数据到集合 ?
使用这个 读写分离集合 CopyOnWriteArrayList

4.7 ArrayList LinkList区别?

ArrayList

基于动态数组的数据结构
对于随机访问的 get set ArrayList 要优于 LinkedList
对于随机操作的 add remove ArrayList 不一定比 LinkedList (ArrayList 底层由于是动态数组,因此 ,并不是每次add remove 的时候都需要创建新数组 )

LinkedList

基于链表的数据结构
对于顺序操作, LinkedList 不一定比 ArrayList
对于随机操作, LinkedList 效率明显较低
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值