ArrayList API 最清晰使用大全

​说到ArrayList,大家一定都不陌生。作为java中常用的集合之一,ArrayList在平常的刷题以及面试中屡见不鲜,其重要性可见一斑。

​ArrayList底层用数组实现,继承了一个抽象类AbstractList,实现了四个接口List、RandomAccess, Cloneable, java.io.Serializable。

​相信ArrayList的原理大家都十分熟悉,毕竟网上博客一搜一大把,而且基本一样(。・ω・。),在这里我就不多bb了。

​本文主要介绍ArrayList各种API的功能以及具体使用方法,保证让你一眼就会,一下就懂

好了,废话不多说,上图!!

在这里插入图片描述
如上图所示,一共15种方法(加上多态可能有二三十种),常用的在左边,不常用的在右边,整体遵循男左女右的原则。

接下来,我将从构造方法开始,以逆时针方向依次介绍各个方法。

1. ArrayList()

1.1ArrayList()

不带参数的构造方法。直接构造一个容量为10的数组来存数据。

说到容量,就不得不说一下ArrayList的扩容机制。ArrayList的底层是用数组实现的,一旦数据的长度超过预先设定的数组长度,就会触发扩容机制。

扩容机制,将创建一个容量为以前数组1.5倍容量的新数组来存放所有的数据,至于为什么是1.5倍,大家有兴趣的可以去看ArrayList的源码。其中,grow()函数详细解释了扩容的整个过程。

值得一提的是,ArrayList在使用不带参的构造方法时,虽然默认容量是10,但第一时间容量为0。只有当调用add()方法往ArrayList中插入第一个元素,也就是ArrayList中存在元素时,容量才会变为10。

public class MyArrayList {

    public static void main(String[] args) {

        ArrayList<Integer> list = new ArrayList<>();
        System.out.println("调用add()之前list容量为:"+getArrayListCapacity(list));
        list.add(52);
        System.out.println("调用add()之后list容量为:"+getArrayListCapacity(list));
        for (int i = 0; i <10 ; i++) {
            list.add(i);
            if (i == 8)
                System.out.println("list中有是"+list.size()+"个元素。"+"当前list容量为"+getArrayListCapacity(list));
            if(i == 9)
                System.out.println("list中有是"+list.size()+"个元素。"+"当前list容量为"+getArrayListCapacity(list));
        }


    }
    
    public static int getArrayListCapacity(ArrayList<?> arrayList) {
        Class<ArrayList> arrayListClass = ArrayList.class;
        try {
            //获取 elementData 字段
            Field field = arrayListClass.getDeclaredField("elementData");
            //开始访问权限
            field.setAccessible(true);
            //把示例传入get,获取实例字段elementData的值
            Object[] objects = (Object[])field.get(arrayList);
            //返回当前ArrayList实例的容量值
            return objects.length;
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        }
    }

}

1.2 ArrayList(int initialCapacity)

带参数的构造方法:参数为初始容量,一旦使用这种声明方法, 无论List中有无元素,初始容量都为设定值。

 ArrayList<Integer> list = new ArrayList<>(5);
        System.out.println("调用add()方法之前List的容量为"+getArrayListCapacity(list));
        list.add(1);
        System.out.println("调用add()方法之后List的容量为"+getArrayListCapacity(list));

在这里插入图片描述

1.3ArrayList(Collection<> c)

带参构造方法:参数为一个集合,及将该集合的元素加入新创建的List中去。

注意:使用这种构造方法时,新创建的List容量为传入集合的大小,并不会初始化为10,再添加新的元素时按扩容机制进行扩容。

        List<Integer> list1 = new ArrayList<>();
        for (int i = 0; i <5 ; i++) {
            list1.add(i);
        }
        ArrayList<Integer> list = new ArrayList<>(list1);
        System.out.println(list);
        System.out.println("调用add()方法之前List的容量为"+getArrayListCapacity(list));
        list.add(6);
        System.out.println("调用add()方法之后List的容量为"+getArrayListCapacity(list));

在这里插入图片描述

2. add()

2.1 add(E e)

往list尾部添加一个元素,这个前面代码中有用到,不多做介绍。函数返回类型为blooean,添加成功则返回true。

2.2 add(int index, E e)

往指定位置添加元素。该函数没有返回值。

        List<Integer> list1 = new ArrayList<>();
        for (int i = 0; i <5 ; i++) {
            list1.add(i);
        }
        System.out.println(list1);
        list1.add(1,10);
        System.out.println(list1);

在这里插入图片描述

2.3 addAll(Collection c)

效果与add(E e)类似,只不过添加的是整个集合中的元素。函数返回类型为blooean,添加成功则返回true。

2.4 addAll(int index, Collection c)

往指定位置之后添加整个集合的元素。函数返回类型为blooean,添加成功则返回true。

List<Integer> list = new ArrayList<>();
for (int i = 0; i <5 ; i++) {
    list.add(i);
}
List<Integer> list1 = new ArrayList<>();
list1.add(12);
list1.add(55);
list1.add(13);
System.out.println(list1);
list1.addAll(1,list);
System.out.println(list1);

在这里插入图片描述

3. get()

get(int index):获取特定位置的元素。比较简单,不多做描述。

4. set()

set(int index , E e):将特定位置的元素更改为e。

List<Integer> list1 = new ArrayList<>();
list1.add(12);
list1.add(55);
list1.add(13);
System.out.println(list1);
list1.set(2,20);
System.out.println(list1);

在这里插入图片描述

5. remove()

5.1 remove(int index)

移除指定位置的元素,并返回该元素。

5.2 remove(Object c)

移除某个特定的元素,返回类型为boolean。注意输入参数只能是对象,当直接输入int类型时,默认为索引。

5.3 removeAll(Collection c)

移除指定集合中的所有元素。返回类型为boolean类型。与之相对的是retainAll(Collection c),两者功能类似,本文不多做讨论。

List<Integer> list = new ArrayList<>();
for (int i = 0; i <11 ; i++) {
    list.add(i*i);
}
System.out.println("当前list集合为:"+list);
int num = list.remove(5);
System.out.println("移除下标为5的元素值:"+num);
System.out.println("当前list集合为:"+list);
Integer integer = 81;
list.remove(integer);
System.out.println("移除81后,list集合为:"+list);
List<Integer> list1 = new ArrayList<>();
list1.add(1);
list1.add(4);
System.out.println("list1集合中的元素为:"+list1);
list.removeAll(list1);
System.out.println("移除list1集合元素后,list集合元素为:"+list);

在这里插入图片描述

6. indexOf()

indexOf(Object c):找到指定元素第一次出现的下标并返回,找到了则返回下标,否则返回-1。

示例程序与LastIndexOf一起。

7. LastIndexOf()

LastIndexOf(Object c):找到元素最后一次出现的下标并返回,找到了则返回下标,否则返回-1。

List<Integer> list = new ArrayList<>();
for (int i = 0; i <11 ; i++) {
    list.add(i*i);
}
list.add(9);
list.add(9);
System.out.println("当前list集合为:"+list);
int num = list.indexOf(9);
System.out.println("元素9第一次出现的位置为:"+num);
int num1 = list.indexOf(5);
System.out.println("元素5第一次出现的位置为:"+num1);
int num2 = list.lastIndexOf(9);
System.out.println("元素9最后一次出现的位置为:"+num2);

在这里插入图片描述

8. trimTosize()

trimTosize():英文中trim有修剪,切去的意思。根据字面意思也能理解,该函数有去掉多余空间的意思。

因为ArrayList的扩容机制,底层数组的容量一般会有多余。所以一般当内存不够时,就会调用trimTosize()去掉多余的空间。

ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i <11 ; i++) {
    list.add(i*i);
}
System.out.printf("当前list中有%d个元素\n",list.size());
System.out.println("当前list容量为:"+getArrayListCapacity(list));
list.trimToSize();
System.out.println("使用trimToSize()之后,list容量为:"+getArrayListCapacity(list));
list.add(1);
System.out.println("扩容后list容量为:"+getArrayListCapacity(list));

在这里插入图片描述

9. ensureCapacity()

ensureCapacity(int minCapacity):手动扩容。

由于ArrayList每次扩容时,都需要去判断数据是够超过容量。当数据量较大,又没有初始化容量时,判断次数大大增多,消耗性能。而ensureCapacity相当于提前告诉了程序需要扩容的 大小,可以提高性能。

int  N = 1000000;
ArrayList<Integer> list = new ArrayList<>();
long startTime = System.currentTimeMillis();
for (int i = 0; i <N ; i++) {
    list.add(i);
}
long endTime = System.currentTimeMillis();
System.out.println("没有使用ensureCapacity时,程序运行时间为:"+(endTime-startTime)+"ms");


ArrayList<Integer> list1 = new ArrayList<>();
list.ensureCapacity(N);
long startTime1 = System.currentTimeMillis();
for (int i = 0; i <N ; i++) {
    list1.add(i);
}
long endTime1 = System.currentTimeMillis();
System.out.println("使用ensureCapacity后,程序运行时间为:"+(endTime1-startTime1)+"ms");

在这里插入图片描述

10. clear()

clear():清空list中元素,没有返回值。

这个比较简单,不过值得一提的是,尽管list中元素清空了,但容量还是没变。也就是说申请的内存并不会被释放,至于什么时候去释放,这就是JVM去干的事情了。

ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i <12 ; i++) {
    list.add(i);
}
System.out.println(list);
System.out.println("使用clear之前容量大小为:"+getArrayListCapacity(list));
list.clear();
System.out.println("使用clear之后容量大小为:"+getArrayListCapacity(list));

在这里插入图片描述

11. clone()

clone():复制一个ArrayList,传到新的list中。

新list的容量并不等于原list的容量,而是等于原数组中元素数量。相当于在原list的基础上用了一次trimToSize()。

ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i <12 ; i++) {
    list.add(i);
}
System.out.println(list);


ArrayList<Integer> list1 = (ArrayList<Integer>) list.clone();
System.out.println("list的容量为:"+getArrayListCapacity(list));
System.out.println(list1);
System.out.println("list1的容量为:"+getArrayListCapacity(list1));

在这里插入图片描述

12.contains()

contains(Object o):判断list中是否包含目标对象,包含则返回true。

这个比较简单,就不举例了。

13. subList()

subList(int fromIndex, int toIndex):从list取出指定范围内的元素组成新的list,遵循左闭右开原则

比如(1,5)就是取出下标为1,2,3,4的四个元素。

List<Integer> list = new ArrayList<>();
for (int i = 0; i <12 ; i++) {
    list.add(i);
}

List<Integer> list1 =  list.subList(1,5);
System.out.println("list中元素为:"+list);
System.out.println("list中(1,5)的元素为:"+list1);

在这里插入图片描述

14. isEmpty()

isEmpty():判断list是否为空,空则返回true。

15. size()

size():返回list中实际元素的个数。

都是看源码还有博客自己学的,大概就这么多东西了,有什么错误的地方欢迎批评指正~( ・´ω`・ )。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值