资讯专栏INFORMATION COLUMN

集合(一) - ArrayList

Barrior / 1078人阅读

一、层级关系

二、初始化方式
(1)List list = new ArrayList<>();

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

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

第一个结论:ArrayList底层是数组

第二个结论:若用无参构造器的方式实例化ArrayList,只是声明了数组,还未分配空间

(2)List list = new ArrayList<>(10);

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

private static final Object[] EMPTY_ELEMENTDATA = {};

补充第二结论:若用有参构造器的方式实例化ArrayList且initialCapacity大于0,则既声明了数组,也分配了空间

三、基本方法的使用 add

流程图

源码解析

public boolean add(E e) {
    //校验数组容量,若空间不够则扩容复制生成一个新的数组
    ensureCapacityInternal(size + 1); 
    //赋值
    elementData[size++] = e;
    return true;
}

private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}

/**
 * 若数组是通过无参构造器的方式实例化的话,返回的minCapacity为10,最后会通过grow方法复制生成一个大小为10的数组
 * 若数组是通过有参构造器的方式实例化的话,返回的minCapacity为当前要操作的数组下标,不建议声明小于10的数组空间,因为这样前几次add都要去扩容复制生成一个新的数组
 */
private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
    grow(minCapacity);
}

//扩容大小:原数组大小 + 原数组大小/2
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);
}

其它说明

初始化ArrayList时,不建议声明小于10的容量,因为这样前几次add都要去扩容复制生成一个新的数组

Arrays.copyOf(T[] original, int newLength):该方法会创建一个新的数组

remove

流程图

源码解析

public E remove(int index) {
    //检查index是否 >= size,若大于则报数组越界异常
    rangeCheck(index);

    modCount++;
    E oldValue = elementData(index);

    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

    return oldValue;
}

其它说明

System.arraycopy - 浅复制

public static void arraycopy(
                             Object src,  //源数组
                             int srcPos,  //源数组要复制的起始位置
                             Object dest, //目标数组
                             int destPos, //目的数组放置的起始位置
                             int length   //复制长度
                             )
四、补充

ArrayList是线程不安全的,表现在多线程下add和remove可能会发生数组越界

不要在foreach循环里进行元素的remove/add操作。remove元素请使用Iterator方式,如果并发操作,需要对Iterator对象加锁

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/71558.html

相关文章

  • 1、自定义类型的定义及使用 2、自定义类的内存图 3、ArrayList集合的基本功能 4、随机点名

    摘要:自定义类的概述自定义类的概述代码映射成现实事物的过程就是定义类的过程。自定义类的格式自定义类的格式使用类的形式对现实中的事物进行描述。 01引用数据类型_类 * A: 数据类型 * a: java中的数据类型分为:基本类型和引用类型 * B: 引用类型的分类 * a: Java为我们提供好的类,比如说:Scanner,Random等。 * b: 我们自己创建的类...

    only_do 评论0 收藏0
  • Java集合源码分析系列-(ArrayList源码剖析

    摘要:需要注意的是,通过构造函数定义初始量是动态数组的实际大小。带容量的构造函数新建一个容量为的数组默认构造函数,默认为空构造一个包含指定元素的第一个构造方法使用提供的来初始化数组的大小。 前言 今天介绍经常使用的一个Java集合类——ArrayList(基于JDK1.8.0_121)。ArrayList在工作和日常面试中经常被使用或者提到。总的来说,工作中使用ArrayList主要是因为动...

    Miyang 评论0 收藏0
  • Java集合框架——List接口

    摘要:第三阶段常见对象的学习集合框架接口按照集合框架的继承体系,我们先从中的接口开始学习一概述及功能演示概述在中充当着一个什么样的身份呢有序的也称为序列实现这个接口的用户以对列表中每个元素的插入位置进行精确地控制。线程不安全,效率高。 第三阶段 JAVA常见对象的学习 集合框架——List接口 showImg(https://segmentfault.com/img/remote/14600...

    褰辩话 评论0 收藏0
  • java集合

    摘要:主要用于遍历集合中的元素,对象也被称为迭代器。使用迭代过程中,不可修改集合元素迭代器采用快速失败机制。一旦迭代过程中检测到该集合已经被修改,程序立即出发异常,而不是显示修改后的结果,避免了共享资源而引发的潜在问题。 集合类和数组不一样,数组元素既可以是基本类型的值,也可以是对象(实际上保存的是对象的引用变量);而集合里只能保存对象(实际上只是保存对象的引用变量,但通常习惯上认为集...

    JinB 评论0 收藏0
  • Java 集合 List

    摘要:集合代表一个元素有序可重复的集合,集合中每个元素都有其对应的顺序索引。集合默认按元素的添加顺序设置元素的索引。 List集合代表一个元素有序、可重复的集合,集合中每个元素都有其对应的顺序索引。List集合可以通过索引来访问指定位置的集合元素。List集合默认按元素的添加顺序设置元素的索引。 Java8改进的List接口和ListIterator接口 普通方法 List是有序集合,因此L...

    AlphaWatch 评论0 收藏0
  • 集合框架源码学习之ArrayList

    摘要:用户自己指定容量创建大小的数组创建空数组默认构造函数,其默认初始容量为构造一个包含指定集合的元素的列表,按照它们由集合的迭代器返回的顺序。以正确的顺序返回该列表中的元素的迭代器。此方法充当基于阵列和基于集合的之间的桥梁。 目录: 0-0-1. 前言 0-0-2. 集合框架知识回顾 0-0-3. ArrayList简介 0-0-4. ArrayList核心源码 0-0-5. Ar...

    BLUE 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<