ArrayList知识点详解

f58f8e3a94e643cea1dfc581478ba6fc.png

目录

1.简介

2.ArrayList的使用

(1)如何实例化ArrayList?(如何创建?)

(2)如何构造使用?

(3)为什么ArrayList的无参构造可以添加数据

(4)ArrayList常见操作 

(5)ArrayList如何遍历

(6)ArrayList的扩容机制

 


 

 

1.简介

ArrayList背后是一个顺序表,顺序表底层是一个数组

04fbbe0063724657a153e34d0e66d23f.png

  1. ArrayList是以泛型方式实现的,使用时必须要先实例化
  2. ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问 
  3. ArrayList实现了Cloneable接口,表明ArrayList是可以clone的
  4. ArrayList实现了Serializable接口,表明ArrayList是支持序列化的
  5. 和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者 CopyOnWriteArrayList
  6. ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表

2.ArrayList的使用

(1)如何实例化ArrayList?(如何创建?)

import java.util.ArrayList;
import java.util.List;

public class Test {
    ArrayList<Integer> arrayList = new ArrayList<>();
    List<Integer> list = new ArrayList<>();
}

有两种方法,区别:list当中的方法相比arraylist较少

d315a40192794d0abaee9924b22ca77d.png

(2)如何构造使用?

2105c9180d944649aa079a677d9dca58.png

Array() 

无参ArrayList()的原码:

public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

 DEFAULTCAPACITY_EMPTY_ELEMENTDATA的原码:

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

说明:常量数组,长度为0 

elementDate的原码:

transient Object[] elementData

说明:element在此处只是一个数组引用,没有进行内存分配 

总结:ArrayList的无参构造方法,并没有给数组分配大小,数组长度为0


ArrayList(int initialCapacity)

ArrayList(int initialCapacity) 原码: 

public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

 说明:传入的值为几,该方法就会给你分配多大的空间

EMPTY_ELEMENTDATA原码:

private static final Object[] EMPTY_ELEMENTDATA = {};

说明:如果传入的值为0时,就会创建一个空数组 

937abc9141f647eebb92d2b50dcf0b32.png

说明:当传入负数时就会抛出异常 

总结:传入的值就是分配给数组的空间,值为0就是空数组,值为负数则抛出异常


 ArrayList(Collection <? extends E>c)  

ArrayList(Collection <? extends E>c)  原码:

public ArrayList(Collection<? extends E> c) {
        Object[] a = c.toArray();
        if ((size = a.length) != 0) {
            if (c.getClass() == ArrayList.class) {
                elementData = a;
            } else {
                elementData = Arrays.copyOf(a, size, Object[].class);
            }
        } else {
            // replace with empty array.
            elementData = EMPTY_ELEMENTDATA;
        }
    }

说明: 

?是E或E 的子类    实现了Collection接口 满足这两种情况即可进行传递

此处arraylist的泛型类型是arraylist3泛型类型的本身,且实现了Collection接口所以可以进行传递

f4a840b7f5d34d67a4eac146302ca965.png

 总结:?是E或E 的子类    实现了Collection接口 满足这两种情况即可进行传递

 (3)为什么ArrayList的无参构造可以添加数据

ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(10);

 add(E e)原码:

d91120a7325a4b46a5df200da632fad4.png

 

说明:把10传进去。此时e为10 ,size为0,elementDate是一个空数组

add(E e, Object[] elementData, int s)原码: 

private void add(E e, Object[] elementData, int s) {
        if (s == elementData.length)
            elementData = grow();
        elementData[s] = e;
        size = s + 1;
    }

 说明:传入的e为10,空数组,s为0;s==0再调用grow()

grow()原码: 

private Object[] grow() {
        return grow(size + 1);
    }

 grow(size + 1)原码:

10d8513adee54c2492d065a0535dbfc0.png

说明:oldCapaticity为0不进入if语句,直接执行else语句,此处返回的是大小为10的数组 

当我们出现执行if语句的情况时,会将原数组空间扩容为原来的1.5倍

总结:当调用不带参数的构造方法进行add的时候,第一次add会分配大小为10的内存 

(4)ArrayList常见操作 

66a678d3c8c04a02bdba38d6e28cb869.png

 

remove :删除元素

有两种操作形式:

  1. 输入下标删除对应下标的值  E remove(int index)
  2. 输入对象直接删除值   boolean remove (Object o)

arrayList.remove(1);//删除1下标的12

arrayList.remove(new Integer(12));//删除12
arrayList.remove(Integer.valueOf(12)));//删除12

addAll(Collection<? extends E> c) :一组数据一次性添加,尾插 c 中的元素

                 ?是E或E 的子类    实现了Collection接口 满足这两种情况即可进行传递

ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(10);
arrayList.add(12);
ArrayList<Integer> arrayList1 = new ArrayList<>();
arrayList1.addAll(arrayList);
System.out.println(arrayList1);

 3e1e6b595ad54dd3b46b7dfad2a859f6.png

 


List subList(int fromIndex, int toIndex)  :截取部分 list,[ )左闭右开

ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(10);
arrayList.add(12);
arrayList.add(23);
arrayList.add(34);
List<Integer> list = arrayList.subList(1,3);
System.out.println(list);

 5daa392350aa4b3fb4a7f443499a9398.png

该方法是在arraylist的基础上截取的,并没有生成新的对象。

dbca6a59232c4c46928db5c9c7702abd.png


E set(int index, Eelement) :用指定的元素(可选操作)替换此列表中指定位置的元素。

ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(10);
arrayList.add(12);
arrayList.add(23);
arrayList.add(34);
List<Integer> list = arrayList.subList(1,3);
arrayList.set(1,99);//1下标更新为99
System.out.println(list);
System.out.println(arrayList);

 e710fe5b0b3b453eb324a2597e6267b1.png

(5)ArrayList如何遍历

ArrayList 可以使用三方方式遍历:for循环+下标、foreach、使用迭代器

public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList<>();
        arrayList.add(10);
        arrayList.add(12);
        arrayList.add(23);
        arrayList.add(34);
        for (int i = 0; i < arrayList.size(); i++) {
            System.out.print(arrayList.get(i) + " ");
        }
        System.out.println();
        for (Integer integer:arrayList) {
            System.out.print(integer + " ");
        }
        System.out.println();
        Iterator<Integer> iterator = arrayList.iterator();
        while (iterator.hasNext()) {
            System.out.print(iterator.next() + " ");
        }
    }

156914c2c4844f899285f1ef074d5e55.png

(6)ArrayList的扩容机制

ArrayList是一个动态类型的顺序表,即:在插入元素的过程中会自动扩容。 

此处跟上面无参构造添加数据的情况基本一致,只不过最后执行的是if语句:

1d5cba06883c4109a5f3b07f027704f0.png

总结:

  1. 检测是否真正需要扩容,如果是调用grow准备扩容  
  2. 预估需要库容的大小 
    初步预估按照1.5倍大小扩容
    如果用户所需大小超过预估1.5倍大小,则按照用户所需大小扩容
    真正扩容之前检测是否能扩容成功,防止太大导致扩容失败
  3. 使用copyOf进行扩容

 

 

 

 

 

 

 

 

  • 19
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值