当前位置: 首页 > news >正文

Java 集合框架之----ArrayList

ArrayList

  1. ArrayList<Integer> list=new ArrayList<Integer> ();用无参构造法创建对象后,这个对象不是null。而是一个有效存在的实例,只不过元素数组为空。
    ArrayList里面可以存放null元素。

  2. Integer.MAX_VALUE 是 Java 中 int 类型的最大值,等于 2^31 - 1(即 2147483647)。
    MAX_ARRAY_SIZEArrayList 中定义的常量,值为 Integer.MAX_VALUE - 8

  • 为什么需要区分
    这个设计与 Java 虚拟机的内存分配机制有关:
    • 数组在内存中存储时,除了元素本身,还需要额外的空间存储数组的元数据(如长度等)
    • 对于某些虚拟机实现,如果数组容量达到 Integer.MAX_VALUE,可能没有足够空间存储元数据,导致内存分配失败
    • MAX_ARRAY_SIZE 预留了 8 个字节的空间,避免这种情况
  • 三目运算符的作用
    return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
    
    • 当所需容量超过 MAX_ARRAY_SIZE 时,尝试使用 Integer.MAX_VALUE(尽最大可能分配)
    • 否则使用 MAX_ARRAY_SIZE(安全的最大容量)

这个逻辑既保证了在大多数情况下的内存分配安全性,又在极端情况下尽可能满足大容量需求,是一种平衡设计。如果直接使用 Integer.MAX_VALUE 作为统一上限,在某些虚拟机环境下可能导致更多的内存分配失败。

  1. ensureCapacityInternal(int minCapacity) 是 Java 中 ArrayList 类的核心方法之一,它的主要作用是确保内部存储数组(elementData)有足够的容量来容纳至少 minCapacity 个元素,是实现动态扩容机制的关键步骤。

具体来说,这个方法的工作流程和作用如下:

  • 特殊空数组的处理
    首先检查当前内部数组 elementData 是否是 DEFAULTCAPACITY_EMPTY_ELEMENTDATA(即通过无参构造函数创建的初始空数组)。
    如果是,则将 minCapacity 修正为「默认容量(通常是 10)」和「传入的 minCapacity」中的较大值。
    这一步的目的是:对于无参构造的 ArrayList,第一次添加元素时会自动应用默认容量(10),避免初始容量过小导致频繁扩容。

  • 触发显式扩容检查
    调用 ensureExplicitCapacity(minCapacity) 方法,进一步判断是否需要扩容:

    • 如果 minCapacity 大于当前 elementData 的长度(即现有容量不足),则触发 grow() 方法进行实际扩容。
    • 同时会更新 modCount(记录结构性修改次数),用于支持快速失败(fail-fast)机制。

简单说,这个方法是 ArrayList 扩容的「前置处理器」:它先根据集合的初始化方式(无参/有参构造)调整最小需求容量,再决定是否需要执行实际的扩容操作,最终保证集合有足够空间存储元素。

  1. Collection<? extends E> c 是 Java 泛型中的一种通配通配符(Upper Bounded Wildcard)语法,表示一个元素类型是 EE 的子类的集合

具体含义拆解:

  • Collection:表示这是一个集合接口(如 ListSet 等都实现了该接口)
  • <? extends E>:泛型通配符,表示集合中的元素类型必须是 E 类型或者 E 的子类(例如 ENumber,则可以接受 IntegerDouble 等类型的集合)
  • c:参数名称,代表传入的集合对象

这个泛型约束的作用:

  • 保证类型安全:确保添加到当前 ArrayList 中的元素类型与集合的泛型类型 E 兼容
  • 提高灵活性:允许传入任何 E 类型子类的集合,比如 ArrayList<Number> 可以接收 ArrayList<Integer> 作为参数
  • 限定只读性:由于使用了 ? extends E,在方法内部不能向集合 c 中添加元素(除了 null),只能读取其中的元素

举例说明:
如果有 ArrayList<Number> list,那么:

  • 可以传入 ArrayList<Integer> 作为参数(因为 IntegerNumber 的子类)
  • 可以传入 ArrayList<Double> 作为参数(因为 DoubleNumber 的子类)
  • 但不能传入 ArrayList<String> 作为参数(类型不兼容)

这种泛型写法既保证了类型安全,又为方法调用提供了灵活性,是 Java 集合框架中常见的设计模式。

  1. remove
 private void fastRemove(int index) {modCount++;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}

用快拷贝的方式将index+1后面的元素拷贝到index中,再把原先最末尾的指针置为null,便于垃圾回收器回收。

  1. Itr 内部类是 ArrayList 实现的迭代器(Iterator),主要作用是提供对 ArrayList 元素的遍历功能,同时保证遍历过程中的线程安全(通过快速失败机制)。

具体来说,Itr 内部类的核心功能和设计目的如下:

  • 实现迭代器接口(Iterator
    Itr 实现了 Iterator<E> 接口,必须重写三个核心方法:

    • hasNext():判断是否还有下一个元素(通过 cursor != size 实现,cursor 是下一个要返回的元素索引)
    • next():返回下一个元素,并移动游标(cursor 自增)
    • remove():删除当前迭代到的元素(通过调用 ArrayListremove 方法实现)
  • 支持集合的安全遍历
    Itr 通过以下机制保证遍历的安全性:

    • 游标跟踪:用 cursor 记录下一个要访问的元素位置,lastRet 记录上一个访问的元素位置,确保遍历顺序正确。
    • 快速失败(fail-fast)
      迭代器初始化时会记录当前 ArrayListmodCount(赋值给 expectedModCount),每次调用 next()remove() 等方法时,都会通过 checkForComodification() 检查 modCount 是否与 expectedModCount 一致。
      如果不一致(表示集合在迭代过程中被结构性修改,如添加/删除元素),会立即抛出 ConcurrentModificationException,避免遍历一个已被修改的、可能不一致的集合。
  • 优化遍历性能
    Itr 被注释为「An optimized version of AbstractList.Itr」,相比父类的迭代器实现,它直接访问 ArrayList 的内部数组 elementData,减少了中间调用开销,提升了遍历效率。

  • 支持函数式遍历
    forEachRemaining(Consumer<? super E> consumer) 方法允许通过 Lambda 表达式遍历剩余元素,例如:

list.iterator().forEachRemaining(element -> System.out.println(element));
http://www.dtcms.com/a/296950.html

相关文章:

  • Effective Modern C++ 条款16:保证const成员函数的线程安全性
  • 网址收集总结
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-17,(知识点:PCB布线,传输线阻抗影响因素)
  • 第一二章笔记
  • [ComfyUI] --ComfyUI 是什么?比 Stable Diffusion WebUI 强在哪?
  • 【STM32项目】智能台灯
  • 无人机保养指南
  • 深入解析Hadoop NameNode的Full GC问题、堆外内存泄漏及元数据分治策略
  • 软件测试的分类
  • C++实现精确延时的方法
  • 季逸超:Manus的上下文工程启示
  • Photoshop下载安装入门教程:从下载安装到第一次完美使用
  • 应急响应】Linux 自用应急响应工具发版 v6.0(LinuxGun)
  • 20 BTLO 蓝队靶场 Sticky Situation 解题记录
  • Voice AI Agent 知识库:打造你自己的语音智能体!
  • Vitest 用法详解及 Coverage Web 工具介绍
  • C# 密封类_密封方法 (seadled 关键字)
  • 【postgresql按照逗号分割字段,并统计数量和求和】
  • 【Spring AI 1.0.0】Spring AI 1.0.0框架快速入门(4)——Chat Memory(聊天记录)
  • SpringCloud【Sentinel】
  • 7.3.2 内核内存管理运行机制
  • 到底可不可以用jion?jion如何优化?
  • MapStruct类型转换接口未自动注入到spring容器中
  • Web前端:JavaScript find()函数内判断
  • Redis 单线程模型与多线程机制
  • kettle 8.2 ETL项目【二、加载数据】
  • 「Linux命令基础」用户和用户组实训
  • rust-方法语法
  • 背包DP之分组背包
  • mac电脑(m1) - flask断点失效