首页 > 编程语言 >Java集合 —— ArrayList详解(源码)

Java集合 —— ArrayList详解(源码)

时间:2025-01-03 16:47:08浏览次数:1  
标签:Object Java int ArrayList elementData 源码 数组 size

我这里阅读的是JDK17关于ArrayList的源码,不过思路都是一样的

简介

  ArrayList 是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。

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

属性设置

// 序列化 Id
private static final long serialVersionUID = 8683452581122892189L;
// 默认初始化容量
private static final int DEFAULT_CAPACITY = 10;
// 空数组
private static final Object[] EMPTY_ELEMENTDATA = {};
// 空数组(如果使用默认构造函数创建,则默认对象内容默认是该值)
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
// 当前数据对象存放地方
transient Object[] elementData; 
// 当前数组长度
private int size;


构造方法

  • 带初始值的构造方法

传入一个初始值,对其进行判断,如果大于0,使用用户的参数初始化,如果等于0,使用空值,都不满足,抛出异常

  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);
      }
  }
  • 无参构造

当创建ArrayList时,不传入参数,直接赋予空值

public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
  • 传入参数为集合的构造方法

这里先将集合转换成数组,在size进行非空判断后,如果传入的参数为 ArrayList,直接将转换为的数组赋值给elementData,如果是其他类型,将转换为的数组复制到新的Object数组中并将其赋值给elementData,如果size为空,赋值为空

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:要添加的元素

  • Object[] elementData:ArrayList 内部存储元素的数组

  • int s:当前 ArrayList 的大小(即元素个数)

将元素e添加到数组elementData中,如果长度不够,调用row()方法进行扩容

private void add(E e, Object[] elementData, int s) {
    if (s == elementData.length)
        elementData = grow();
    elementData[s] = e;
    size = s + 1;
}
  • 返回布尔值的添加方法,接收一个参数

和上面的E是一样的,modCount是 AbstractList 中的一个属性,代表修改计数器,对修改次数进行记录,通过上一个add(E e, Object[] elementData, int s)进行添加

public boolean add(E e) {
    modCount++;
    add(e, elementData, size);
    return true;
}
  • 插入到指定位置的添加方法

通过rangeCheckForAdd()方法对索引进行检查,如果小于0或者大于size,抛出异常,对修改次数进行修改,检查数组是否需要扩容,之后对元素进行移动,插入新元素,修改size

public void add(int index, E element) {
    rangeCheckForAdd(index);
    modCount++;
    final int s;
    Object[] elementData;
    if ((s = size) == (elementData = this.elementData).length)
        elementData = grow();
    System.arraycopy(elementData, index,
                     elementData, index + 1,
                     s - index);
    elementData[index] = element;
    size = s + 1;
}


扩容

  • 对ArrayList的内部数组进行扩容
  • 如果当前数组容量大于 0,按一定的规则计算新容量并扩容。

  • 如果当前数组为空且不是默认的空数组,按一定的规则计算新容量并扩容。

  • 如果当前数组是默认的空数组,直接创建一个新数组。

先获取当前数组容量,判断当前数组是否需要扩容,如果需要,计算所需扩容量,创建新数组并赋值数据,如果不需要返回默认空数组

private Object[] grow(int minCapacity) {
    int oldCapacity = elementData.length;
    if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        int newCapacity = ArraysSupport.newLength(oldCapacity,
                minCapacity - oldCapacity, /* minimum growth */
                oldCapacity >> 1           /* preferred growth */);
        return elementData = Arrays.copyOf(elementData, newCapacity);
    } else {
        return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
    }
}

图解


标签:Object,Java,int,ArrayList,elementData,源码,数组,size
From: https://www.cnblogs.com/codyxz/p/18649631

相关文章

  • JavaMock批量生成GET SET方法单测覆盖率
    @RunWith(MockitoJUnitRunner.class)@Slf4jpublicclassPersonTest{@TestpublicvoidtestPerson(){MockGetSetMethod(Person.class);}/***@paramtClass需要生成覆盖率的实体类*@param<T>泛型*/public<T>......
  • delphi djson 类与JSON 互转,与 Java、Golang 一致写法
    前因为什么要开发这个JSON库?原因是delphi官方的json既没有处理null(也叫零值)的问题;举例说明吧:开发者往往需要类与JSON之间进行序列化和反序列化;接下来我们举个例子:Person{id:Int64;//IDname:string;//姓名desc:string;//描述}这样一个类在不......
  • java字符串拼接遇到null你会处理吗
    现有一个场景,对于发票信息,需要把信息中的地址和电话进行拼接,开户号和账号进行拼接,那应该怎么做?最简单的方法是使用+拼接,但问题是如果有个字段为空,是null,那么拼接结果是什么样的?来个下面的示例publicstaticvoidmain(String[]args){Stringa=null;String......
  • 深入理解 Java Set 集合:原理、应用与高频面试题解析
    深入理解JavaSet集合:原理、应用与高频面试题解析在Java中,Set是一种重要的集合接口,用于存储不重复的元素。无论是在实际开发中,还是在面试场景中,Set都是一个高频的知识点。本篇文章将详细介绍JavaSet集合的基础知识、常见实现类、应用场景以及面试常考题,最后通过总结帮助......
  • DispatcherServlet 请求处理源码分析
    业务处理流程请求匹配:通过HandlerMapping查找合适的处理器。拦截器前置处理:执行所有的HandlerInterceptor的preHandle方法。执行控制器方法:调用相应的控制器方法处理请求。数据处理:如果是视图返回,进行视图解析并渲染。如果是数据返回,使用HttpMessageConverter转换......
  • 利用JAVA爬虫获取item_search_img-按图搜索1688商品(拍立淘)接口
    引言在当今的电商领域,图像识别技术的应用越来越广泛,尤其是以图搜图功能,它极大地提高了用户的购物体验。本文将详细介绍如何利用JAVA爬虫技术获取1688商品的按图搜索接口,即拍立淘接口,实现商品的图像识别搜索。一、1688API接口概述1688作为阿里巴巴集团旗下的批发交易平台,提......
  • 酒店管理系统|Java|SSM|VUE| 前后端分离
                 【技术栈】1⃣️:架构:B/S、MVC2⃣️:系统环境:Windowsh/Mac3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7+4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html5⃣️数据库可视化工具:navicat6⃣️服务器:SpringBoot自带apachetomca......
  • 咖啡馆系统|Java|SSM|JSP|
                                             【技术栈】1⃣️:架构:B/S、MVC2⃣️:系统环境:Windowsh/Mac3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7+4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、JSP、jquery,html5⃣️数据库可视化工......
  • 教学质量评价系统|Java|SSM|JSP| 
                 【技术栈】1⃣️:架构:B/S、MVC2⃣️:系统环境:Windowsh/Mac3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7+4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、JSP、jquery,html5⃣️数据库可视化工具:navicat6⃣️服务器:SpringBoot自带apachetomca......
  • 2025最新Java八股文(完整版)
    JAVA基础八股文问:java中序列化是怎么实现的呢?1.实现Serializable接口,就会实现数据序列化的效果。2.调用json做序列化。(就比如:Jackson,fastjson等等)3.实现Enternalizable接口,就可以实现反序列化的效果。问:java的流有哪些呢?从方向方面,主要就是输入流和输出流。从单位方面,......