java-集合框架库-ArrayList

目录

1方法

2源码实现

2.1继承关系

2.2构造函数

2.3属性信息

2.4默认值或默认属性

2.5底层数据结构

2.6扩容机制

2.7常用方法研究

2.7.1add()

2.7.2get(int index)

2.7.3remove(Object o) 删除

3特点总结


 

ArrayList 继承了 AbstractList ,并实现了 List 接口。

1方法

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 中每一个元素并执行特定操作

2源码实现

2.1继承关系

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接口 表明当前类是可以支持序列化和反序列化)

2.2构造函数

//通过 初始容量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);
    }

2.3属性信息

//存储元素位置
private transient Object[] elementData;
//存储元素个数
private int size;
//父类提供的属性 记录集合数据变更版本值(新增、修改、删除) ,和业务无关
private int modcount  修改版本号

2.4默认值或默认属性

//默认的数组初始容量
private static final int DEFAULT_CAPACITY = 10;
//空数组实例
private static final Object[] EMPTY_ELEMENTDATA = {};

2.5底层数据结构

底层数据结构是:数组

2.6扩容机制

//扩容大小  
int newCapacity = oldCapacity + (oldCapacity >> 1);

//arraylist集合扩容时按照1.5倍进行扩容

2.7常用方法研究

2.7.1add()

    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;
    }

 
add过程:
1、如果存储数组为空,获取默认的大小值是10
2、如果需要大小超过数组大小、考虑扩容,按照原数组大小的1.5倍扩容
3、通过创建新数组,将元素组大小拷贝到新数组中
4、将新增元素插入最后的size位置并对size进行加1操作

public void add(int index, E element) 添加数据;在指定位置添加数据,需要保证index合法,并将index之后的数据后移以为,然后插入新值

2.7.2get(int 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));
    }

2.7.3remove(Object o) 删除

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
    }

ArrayList和数组区别?

1、ArrayList底层封装数组,提供了丰富API操作

2、存储数据:ArrayList存储的是自定义对象,基本包装类型,不能存储基本类型,即使我们可以向里面put一个基本数据类型,那么也是基于自动装箱特性,将基本数据类型转换成对象;  数组可以存放自定义类型,包装类型、基类类型(int)

基本类型对应的包装类表如下:

基本类型引用类型
booleanBoolean
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter

此外,BigInteger、BigDecimal 用于高精度的运算,BigInteger 支持任意精度的整数,也是引用类型,但它们没有相对应的基本类型。

3、ArrayList是可以自动扩容的 ,数组不能自动扩容

3特点总结

①插入有序

②数据可以重复

③可以存储null值

④底层数据结构是数组

⑤可以动态扩容

⑥线程不安全

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值