赞
踩
目录
ArrayList 继承了 AbstractList ,并实现了 List 接口。
ArrayList 常用方法列表如下:
方法 | 描述 |
---|---|
add() | 将元素插入到指定位置的 arraylist 中 |
addAll() | 添加集合中的所有元素到 arraylist 中 |
clear() | 删除 arraylist 中的所有元素 |
clone() | 复制一份 arraylist |
contains() | 判断元素是否在 arraylist |
get() | 通过索引值获取 arraylist 中的元素 |
indexOf() | 返回 arraylist 中元素的索引值 |
removeAll() | 删除存在于指定集合中的 arraylist 里的所有元素 |
remove() | 删除 arraylist 里的单个元素 |
size() | 返回 arraylist 里元素数量 |
isEmpty() | 判断 arraylist 是否为空 |
subList() | 截取部分 arraylist 的元素 |
set() | 替换 arraylist 中指定索引的元素 |
sort() | 对 arraylist 元素进行排序 |
toArray() | 将 arraylist 转换为数组 |
toString() | 将 arraylist 转换为字符串 |
ensureCapacity() | 设置指定容量大小的 arraylist |
lastIndexOf() | 返回指定元素在 arraylist 中最后一次出现的位置 |
retainAll() | 保留 arraylist 中在指定集合中也存在的那些元素 |
containsAll() | 查看 arraylist 是否包含指定集合中的所有元素 |
trimToSize() | 将 arraylist 中的容量调整为数组中的元素个数 |
removeRange() | 删除 arraylist 中指定索引之间存在的元素 |
replaceAll() | 将给定的操作内容替换掉数组中每一个元素 |
removeIf() | 删除所有满足特定条件的 arraylist 元素 |
forEach() | 遍历 arraylist 中每一个元素并执行特定操作 |
- public class ArrayList<E> extends AbstractList<E>
- implements List<E>, RandomAccess, Cloneable, java.io.Serializable
-
ArrayList继承自AbstractList (AbstractList类是抽象类实现自List接口,对接口中通用的方法做了实现,子类可以不用实现,子类如果有特殊需求可以重写对应方法)
ArrayList实现接口List、RandomAccess、Cloneable、Serializable
(List接口 是ArrayList、Linkedlist的接口,定义了集合中大部分方法;
RandomAccess接口 表明当前类可以随机访问;
Cloneable接口 表明当前类是可以被克隆;
Serializable接口 表明当前类是可以支持序列化和反序列化)
- //通过 初始容量initialCapacity参数 来实例化ArrayList
- public ArrayList(int initialCapacity) {
- super();//继承父类中的初始化方法
- //参数校验
- if (initialCapacity < 0)
- throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);
- //创建指定大小的数组实例
- this.elementData = new Object[initialCapacity];
- }
-
- //无参构造函数
- public ArrayList() {
- super();
- //给定空的数组
- this.elementData = EMPTY_ELEMENTDATA;
- }
-
-
- //通过 集合实例 来实例化ArrayList
- public ArrayList(Collection<? extends E> c) {
- elementData = c.toArray();
- size = elementData.length;
- // c.toArray might (incorrectly) not return Object[] (see 6260652)
- if (elementData.getClass() != Object[].class)
- //完成数据拷贝
- elementData = Arrays.copyOf(elementData, size, Object[].class);
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- //存储元素位置
- private transient Object[] elementData;
- //存储元素个数
- private int size;
- //父类提供的属性 记录集合数据变更版本值(新增、修改、删除) ,和业务无关
- private int modcount 修改版本号
- //默认的数组初始容量
- private static final int DEFAULT_CAPACITY = 10;
- //空数组实例
- private static final Object[] EMPTY_ELEMENTDATA = {};
底层数据结构是:数组
- //扩容大小
- int newCapacity = oldCapacity + (oldCapacity >> 1);
-
- //arraylist集合扩容时按照1.5倍进行扩容
- public boolean add(E e) {
- ensureCapacityInternal(size + 1); // Increments modCount!!
- //将新增元素插入elementData数组中
- elementData[size++] = e;
- return true;
- }
- private void ensureCapacityInternal(int minCapacity) {
- //当数组为空时,获取当前容量值
- if (elementData == EMPTY_ELEMENTDATA) {
- //当无参构造的实例时,第一次会进入该方法
- minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
- }
-
- ensureExplicitCapacity(minCapacity);
- }
- private void ensureExplicitCapacity(int minCapacity) {
- modCount++;
-
- //数据空间不足,考虑扩容
- if (minCapacity > elementData.length )
- grow(minCapacity);
- }
-
- private void grow(int minCapacity) {
- // overflow-conscious code
- int oldCapacity = elementData.length;
- //扩容大小
- int newCapacity = oldCapacity + (oldCapacity >> 1);
- //扩容范围的限制
- if (newCapacity - minCapacity < 0)
- newCapacity = minCapacity;
- if (newCapacity - MAX_ARRAY_SIZE > 0)
- newCapacity = hugeCapacity(minCapacity);
- // minCapacity is usually close to size, so this is a win:
- //创建新的指定大小的集合,将原有数据拷贝到新数组中
- elementData = Arrays.copyOf(elementData, newCapacity);
- }
-
- private static int hugeCapacity(int minCapacity) {
- if (minCapacity < 0) // overflow
- throw new OutOfMemoryError();
- return (minCapacity > MAX_ARRAY_SIZE) ?
- Integer.MAX_VALUE :
- MAX_ARRAY_SIZE;
- }
-
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
add过程:
1、如果存储数组为空,获取默认的大小值是10
2、如果需要大小超过数组大小、考虑扩容,按照原数组大小的1.5倍扩容
3、通过创建新数组,将元素组大小拷贝到新数组中
4、将新增元素插入最后的size位置并对size进行加1操作
public void add(int index, E element) 添加数据;在指定位置添加数据,需要保证index合法,并将index之后的数据后移以为,然后插入新值
- public E get(int index) {
- //检查下标的合法性 0<= index <size
- rangeCheck(index);
- //通过下标指定位置来获取数据
- return elementData(index);
- }
-
- private void rangeCheck(int index) {
- if (index >= size)
- throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
- }
remove(int index) 删除
- public boolean remove(Object o) {
- if (o == null) {
- //元素为空时
- for (int index = 0; index < size; index++)
- if (elementData[index] == null) {
- fastRemove(index);
- return true;
- }
- } else {
- //不为空
- for (int index = 0; index < size; index++)
- if (o.equals(elementData[index])) {
- fastRemove(index);
- return true;
- }
- }
- return false;
- }
-
- //将index后续的数据前移一位
- private void fastRemove(int index) {
- modCount++;
- int numMoved = size - index - 1;
- if (numMoved > 0)
- System.arraycopy(elementData, index+1, elementData, index,
- numMoved);
- elementData[--size] = null; // clear to let GC do its work
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
ArrayList和数组区别?
1、ArrayList底层封装数组,提供了丰富API操作
2、存储数据:ArrayList存储的是自定义对象,基本包装类型,不能存储基本类型,即使我们可以向里面put一个基本数据类型,那么也是基于自动装箱特性,将基本数据类型转换成对象; 数组可以存放自定义类型,包装类型、基类类型(int)
基本类型对应的包装类表如下:
基本类型 | 引用类型 |
---|---|
boolean | Boolean |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
此外,BigInteger、BigDecimal 用于高精度的运算,BigInteger 支持任意精度的整数,也是引用类型,但它们没有相对应的基本类型。
3、ArrayList是可以自动扩容的 ,数组不能自动扩容
①插入有序
②数据可以重复
③可以存储null值
④底层数据结构是数组
⑤可以动态扩容
⑥线程不安全
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。