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

从Java ArrayList 学习泛型设计

ArrayList的泛型设计分析

ArrayList是Java集合框架中一个非常重要的类,它巧妙地结合了泛型和Object数组来实现类型安全和高效的元素存储。下面我们来详细分析其设计的巧妙之处:


泛型声明与内部数组

​源码位置:​ArrayList.java

public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable {// ...transient Object[] elementData; // non-private to simplify nested class access// ...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);}}}
  • 使用泛型参数 E 表示列表中存储的元素类型
  • 内部采用 Object[] 数组存储元素(可容纳任意类型对象)

类型安全的实现

虽然内部使用 Object 数组存储元素,但通过泛型机制确保类型安全。在元素访问时,通过强制类型转换将 Object 转换为泛型类型 E

@SuppressWarnings("unchecked")
E elementData(int index) {return (E) elementData[index];  // 强制类型转换(编译器无法运行时验证类型安全)
}public E get(int index) {Objects.checkIndex(index, size);return elementData(index);
}
  • @SuppressWarnings("unchecked") 用于抑制编译器对类型转换的警告

添加元素的实现

public boolean add(E e) {modCount++;add(e, elementData, size);return true;
}private void add(E e, Object[] elementData, int s) {if (s == elementData.length)elementData = grow();elementData[s] = e;  // 直接存储泛型元素(依赖类型擦除特性)size = s + 1;
}
  • 利用Java泛型类型擦除特性:运行时所有泛型类型均视为 Object 类型

迭代器中的泛型处理

private class Itr implements Iterator<E> {// ...@SuppressWarnings("unchecked")public E next() {checkForComodification();int i = cursor;if (i >= size)throw new NoSuchElementException();Object[] elementData = ArrayList.this.elementData;if (i >= elementData.length)throw new ConcurrentModificationException();cursor = i + 1;return (E) elementData[lastRet = i];  // Object→泛型类型转换}// ...
}

toArray方法的泛型处理

​源码位置:​ArrayList.java

@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {if (a.length < size)// 创建与输入数组运行时类型相同的新数组return (T[]) Arrays.copyOf(elementData, size, a.getClass());System.arraycopy(elementData, 0, a, 0, size);if (a.length > size)a[size] = null;return a;
}
  • 通过传入数组类型 T 确定返回数组类型,并执行 Object[] 到指定类型数组的转换

sort方法

巧妙结合泛型与Object数组实现类型安全且高效的排序。

    private void sortRange(Comparator<? super E> c, int fromIndex, int toIndex) {final int expectedModCount = modCount; // 记录初始修改计数Arrays.sort((E[]) elementData, fromIndex, toIndex, c); // 调用JDK排序if (modCount != expectedModCount) throw new ConcurrentModificationException(); // 并发修改检查
    }
    1. ​底层存储​​:
      elementDataObject[] 类型数组,实际存储列表的所有元素。

    2. ​类型转换​​:
      elementData 强制转换为 E[] 后传入 Arrays.sort
      ​安全性保障​​:ArrayList内部严格保证只存储类型 E 的元素,因此运行时转换是安全的(依赖泛型擦除后实际为 Object[] 的特性)。【注意null也是类型E,因此new Object[cap]创建的也是E[ ]

    3. ​性能优化​​:
      直接复用JDK Arrays.sort 的高效实现,通过泛型擦除在编译期保证类型安全,运行时无额外开销。

    http://www.dtcms.com/a/389481.html

    相关文章:

  • 【Amber报错1】 Amber/Miniconda 与系统 Bash 的 libtinfo.so.6冲突
  • AI智慧能力的核心引擎,自注意力机制
  • 35、模型量化与压缩实践
  • LeetCode 16.最接近的三数之和
  • 深入解析Redis集群模式:构建高可用与可扩展的缓存系统
  • 小麦病害检测识别数据集:1k图像,4类,yolo标注
  • Python读取excel表格并写入数据库
  • 【LeetCode 每日一题】1317. 将整数转换为两个无零整数的和
  • 论文投稿信(Cover Letter)
  • WPF——DataGrid
  • 物联网智能电表平台:所有电表数据,集中到一个系统管
  • Python自学19-Python操作Word和PowerPoint文件
  • Android使用GPU指南
  • 贪心算法应用:装箱问题(BFD算法)详解
  • 如何入门到实战策略学习ETF期权?
  • 贪心算法应用:最小反馈顶点集问题详解
  • 物联网与智能体:下一代数字化生态的关键
  • 关于lvs+keeplived在mysql分库分上负载部署
  • Springboot获取bean的工具类
  • C++学习日记
  • DRAM的原理
  • Ansible插件开发
  • ubuntu 两个网卡进行映射
  • 通信高效的数据并行分布式深度学习-综述-图表解读
  • 为何我的无刷电机在FOC开环控制下迅速发烫?
  • Docker多容器编排:Compose 实战教程——深入探索与实践
  • 网络交换机分类与功能解析
  • FPGA学习笔记——Vivado创建工程(2022版)
  • Python 美食菜谱可视化:Django 后端 + Vue 前端 + 豆果爬虫 + Echarts(大数据方向)(建议收藏)✅
  • 【从入门到精通Spring Cloud】声明式服务调用组件OpenFeign