一篇文章让你轻松理解ArrayList

目录

一、ArrayList是什么?

二、使用ArrayList

1.ArrayList的构造

2.ArrayList方法

3.ArrayList的遍历

4.ArrayList的扩容机制

总结


一、ArrayList是什么?

ArrayList是Java编程语言中的一个类,它实现了动态数组的功能。它可以存储任意类型的对象,并且在需要时可以根据需要自动扩展大小。ArrayList提供了一系列方法来操作和管理存储在其中的元素。

二、使用ArrayList

1.ArrayList的构造

// 构造一个空的列表
List<Integer> list1 = new ArrayList<>();
// 构造一个具有10个容量的列表
List<Integer> list2 = new ArrayList<>(10);
list2.add(1);
list2.add(2);
list2.add(3);

2.ArrayList方法

public int[] elem;//定义了一个数组
    public int usedSize;//0

    public static final int default_size = 10;
    //顺序表默认大小  初始化了一个值

    public MyArrayList(){
        this.elem = new int[default_size];//直接初始化一个数组
    }

    public MyArrayList(int size){
        this.elem = new int[size];
        //默认一个数组长度
    }
//新增元素,默认在数组最后新增
public void add(int data);
@Override
    public void add(int data) {
        check();

       this.elem[this.usedSize] = data;
       this.usedSize++;
    }

    private void check(){
        if(isFull()){
            //扩容
            Arrays.copyOf(elem,elem.length*2);
        }
    }
//在pos位置新增元素
public void add(int pos,int data);//这两个构成了方法的重载
 @Override
    public void add(int pos, int data) {
        try{
            checkPosOnAdd(pos);
        }catch (PosIllegality e){
            e.printStackTrace();
            return;
        }//打印异常点

        check();

        //从最后一个有效的数据开始往后移动
        for (int i =  usedSize-1; i >= pos; i--) {
            elem[i+1] = elem[i];
        }
        //当i<pos就结束
        elem[pos] = data;
        //存放元素到pos位置
        usedSize++;
        //usedsize++;
    }
/*
*检查pos的合法性
*
 */
    private void checkPosOnAdd(int pos){
        if(pos < 0 || pos >usedSize){
            System.out.println("不符合法");
            throw new PosIllegality("插入元素下标异常"+pos);
        }
    }
//判定是否包含某个元素
public  boolean contains(int toFind);
 @Override
    public boolean contains(int toFind) {
        if(isEmpty()){
            return false;
        }
        for (int i = 0; i < usedSize; i++) {
            //如果是查找引用数据类型 一定记住 重写方法
            if(elem[i] == toFind){
                return true;
            }
        }
        return false;
    }
// 获取pos 位置的元素
public int get(int pos);
@Override
    public int get(int pos) throws MyArrayListEmpy {

        checkPosOnGetAddSet(pos);
        if(isEmpty()){
                throw new MyArrayListEmpy("获取指定下标元素时"+"顺序表为空!");

        }
        return elem[pos];
    }
public void set(int pos,int value);
//给pos位置的元素设为value
private void checkPosOnGetAddSet(int pos) throws PosIllegality{
        if(pos < 0 || pos >usedSize){
            System.out.println("不符合法");
            throw new PosIllegality("插入元素下标异常"+pos);
        }
    }

    @Override
    public void set(int pos, int value) {
        checkPosOnGetAddSet(pos);

        elem[pos] = value;
    }

public void remove(int toRemove);
//删除第一次出现的关键字key
@Override
    public void remove(int toRemove) {
    int index = indexOf(toRemove);
    if(index == -1){
    System.out.println("没有这个数字");
    return;
}
        for (int i = index; i < usedSize-1; i++) {
            elem[i]= elem[i+1];
        }
        usedSize--;
    }
public int size();
//获取顺序表长度
 @Override
    public int size() {
        return this.usedSize;
    }

3.ArrayList的遍历

ArrayList 可以使用两方式遍历:for循环+下标、foreach、

public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
// 使用下标+for遍历
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + " ");
}
System.out.println();
// 借助foreach遍历
for (Integer integer : list) {
System.out.print(integer + " ");
}
System.out.println();
Iterator<Integer> it = list.listIterator();
while(it.hasNext()){
System.out.print(it.next() + " ");
}
System.out.println();
}

4.ArrayList的扩容机制

ArrayList 是 Java 中常用的动态数组实现类,其扩容机制是指在 ArrayList 添加元素时,当内部数组已满时,会自动进行扩容操作,以容纳更多的元素。下面是 ArrayList 的扩容机制的简要说明:

  1. 初始容量:ArrayList 在创建时,会初始化一个默认的初始容量,通常为 10。这意味着,在 ArrayList 中最初可以存储 10 个元素。

  2. 扩容条件:当 ArrayList 中的元素个数(即 size)达到当前内部数组的容量时,就会触发扩容操作。

  3. 扩容策略:ArrayList 的默认扩容策略是将当前容量增加到原容量的 1.5 倍(即扩容为原容量的 150%),然后创建一个新的内部数组,并将所有元素从旧数组复制到新数组中。

以下是ArrayList源码中扩容方式:

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private void grow(int minCapacity) {
// 获取旧空间大小
int oldCapacity = elementData.length;
// 预计按照1.5倍方式扩容
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 如果用户需要扩容大小 超过 原空间1.5倍,按照用户所需大小扩容
if (newCapacity - minCapacity < 0)

newCapacity = minCapacity;
// 如果需要扩容大小超过MAX_ARRAY_SIZE,重新计算容量大小
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 调用copyOf扩容
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
// 如果minCapacity小于0,抛出OutOfMemoryError异常
if (minCapacity < 0)
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}
1. 检测是否真正需要扩容,如果是调用grow准备扩容
2. 预估需要库容的大小
初步预估按照1.5倍大小扩容
如果用户所需大小超过预估1.5倍大小,则按照用户所需大小扩容
真正扩容之前检测是否能扩容成功,防止太大导致扩容失败
3. 使用copyOf进行扩容


总结

以上就是今天要讲的内容,希望大家多多支持。

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

所遇皆随风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值