Java动态数组(一)

Java动态数组(一)

  • 前提概要
  • 创建动态数组
    • 泛型
    • 基本数据类型的封装类
  • 常用操作方法
    • 与静态数组的方法对比
  • 下期预告

前提概要

在《C 语言实现数组动态扩容》一文中,我们已经介绍了 C 语言中数组动态扩容的实现方式。实际上,在 Java 中同样可以实现类似的效果。

  • 必备知识:Java数组

创建动态数组

在 Java 中,我们不需要像在 C 语言中那样手动分配内存。Java 已经为我们提供了现成的动态数组实现 ——ArrayList,它是一个可以自动扩容的“可变长数组”。

它的底层原理其实并不复杂:

  • 本质上依然是一个普通数组;
  • 当元素装满后,会自动申请一个更大的数组,并将原数组中的元素复制过去;
  • 因此,我们只需关心“往里添加元素”,而无需担心容量是否足够。

创建ArrayList的示例代码如下(第一行import是把ArrayList这个类引入当前文件,不要忘记加!):

importjava.util.ArrayList;ArrayList<String>list1=newArrayList<>();

下面逐段拆解这行代码:

  1. ArrayList:类名,表示“动态数组”这个现成的类。
  2. <String>:泛型,表示该列表只能存储String类型的元素。
    • 指定<String>后,如果执行list.add(100),编译器会直接报错。
    • 如果不写泛型(如ArrayList list2 = new ArrayList<>()),则列表可以存储任意类型的元素。
  3. new ArrayList<>():创建对象。后面的<>中无需再次指定类型,编译器会自动推断。()里还可以传一个整数,比如new ArrayList<>(20),用来设置初始容量,表示一开始先预留 20 个存储位置;如果已经知道大概要存多少个元素,提前设置可以减少自动扩容次数。不传也没关系,默认会自动处理,后续元素超出容量时仍然会自动扩容。

泛型

ArrayList<String>中的<String>就叫“泛型”,它用来限定这个动态数组只能存放哪一种类型的数据。

除了String,你还可以根据实际需要指定其他类型,例如:

  • ArrayList<Integer>:只能存放整数;
  • ArrayList<Double>:只能存放小数;

注意:尖括号里不能写基本类型,比如int,必须写成对应的包装类Integer。

基本数据类型的封装类

Java 有 8 种基本数据类型,但它们都是关键字,不是一个真正的类。为了让基本类型也能像对象一样使用,比如存进集合、调用方法等,Java 针对每种基本数据类型都定义了对应的类,这些类统称为「封装类」。

常见对应关系如下:

  • int→Integer(整型 → 整数封装类)
  • byte→Byte(字节型 → 字节封装类)
  • long→Long(长整型 → 长整型封装类)
  • float→Float(单精度浮点型 → 单精度浮点封装类)
  • double→Double(双精度浮点型 → 双精度浮点封装类)

自动装箱与自动拆箱

一般情况下,使用int和Integer没有明显区别,这主要依赖自动装箱和自动拆箱:

inta=100;// 自动装箱:把一个普通整数变量,存入 Integer 对象变量中Integera1=a;// 自动拆箱:把 Integer 对象变量转为基本类型整数变量inta2=a1;

封装类的独特优势

封装类最大的好处就是:它本质是一个真正的类,可以直接调用现成的方法。

基本类型只是一个数据,比如:

inta=100;// 在这里敲 a. 不会弹出任何方法,因为 int 不是对象

而换成封装类之后:

Integerb=100;// 在这里敲 b. 会弹出一堆现成的方法,直接用就行

下面按用途把常用的方法整理成几类。

1. 字符串和数字互相转换

  • Integer.parseInt("250"):把“字符串形式的数字”转成真正的数字,常用于处理用户输入、文件读取等场景。
  • b.toString():把Integer对象转回字符串,例如b.toString()会得到"100"。
intnum=Integer.parseInt("250");// 字符串 "250" 变成数字 250Strings=b.toString();// Integer 对象变成字符串 "100"

2. 比较大小、取最大值/最小值

  • Integer.max(10, 20):返回两个数中的较大值,例如结果是20。
  • Integer.min(10, 20):返回两个数中的较小值,例如结果是10。
  • b.compareTo(200):比较b和200的大小,返回一个int类型的结果:结果为-1表示b比200小,等于0表示两者相等,结果为1表示b比200大。

3. 类型转换

  • b.intValue():把Integer对象转成int基本类型。
  • b.doubleValue():把Integer对象转成double基本类型。

4. 获取常量或边界值

  • Integer.MAX_VALUE:直接获取int的最大值2147483647。
  • 同理,Integer.MIN_VALUE可以获取int的最小值。

5. 进制转换

  • Integer.toBinaryString(10):把十进制整数10转成二进制字符串,结果是"1010"。
inta=10;Stringbin=Integer.toBinaryString(a);// 得到 "1010"

使用注意事项

  • 定义List这类集合时,泛型必须写Integer,不能写int。
  • 比较两个Integer时,建议使用equals()而不是==。因为==比较的是对象地址,equals()比较的才是具体内容。

例如:

Integerb1=1828;Integerb2=1828;System.out.println(b1==b2);// false,超出缓存范围后比较的是对象地址System.out.println(b1.equals(b2));// true,比较的是具体内容// 定义 List 时,泛型使用 IntegerArrayList<Integer>list2=newArrayList<>();

常用操作方法

ArrayList的常用方法可以按「增删改查」来记忆。下面先用一张表快速浏览,再配合一段示例代码。

操作代码说明
添加list.add("abc")添加到末尾
插入list.add(0, "abc")插入到指定位置,原有元素会向后移
获取list.get(0)取第 0 个元素,索引从 0 开始
修改list.set(0, "xyz")把第 0 个元素换成"xyz"
删除list.remove(0)删除第 0 个元素
按内容删除list.remove("abc")删除第一个值为"abc"的元素
清空list.clear()删除全部元素,但集合对象还在
长度list.size()获取元素个数,注意不是数组的length
是否为空list.isEmpty()没有元素时返回true
是否包含list.contains("abc")是否包含该元素,返回true或false
查找位置list.indexOf("abc")返回第一次出现的位置,不存在时返回-1

与静态数组的方法对比

静态数组创建后长度固定,也没有add()、remove()这些方法;ArrayList因为是真正的类,所以几乎所有操作都可以“点方法”完成。下面把同一个需求放到一起对比:

需求静态数组写法ArrayList写法
创建容器String[] arr = new String[3];ArrayList<String> list = new ArrayList<>();
添加元素arr[0] = "abc";list.add("abc");
插入元素需要手写移动逻辑,很麻烦list.add(0, "top");
获取元素arr[0]list.get(0)
修改元素arr[0] = "xyz";list.set(0, "xyz");
删除元素arr[0] = null;(只是置空,不是真正删除)list.remove(0);
获取长度arr.length(没有括号,是属性)list.size()(有括号,是方法)
是否包含需要自己写循环判断list.contains("abc");
是否为空需要自己判断arr.length == 0list.isEmpty();

从表中可以看到两个关键区别:

  1. 静态数组的长度是固定的,创建时就要指定大小;ArrayList会自动扩容,添加元素时不用提前考虑容量。
  2. 静态数组通过“下标 + 赋值”操作,ArrayList通过方法调用操作:数组有length属性,ArrayList用size()方法;ArrayList还能直接调用add()、remove()、contains()等现成方法。

关于「打印」和「排序」,两者都能做到,但写法不一样,而且不是都能直接toString打印出内容。

1. 打印内容:toString()

  • ArrayList重写了toString(),直接打印就能看到元素内容:
ArrayList<String>list=newArrayList<>();list.add("张三");list.add("李四");System.out.println(list);// [张三, 李四]
  • 静态数组不能直接打印出内容,直接打印会得到类似[Ljava.lang.String;@1b6d3586这样的“类型@地址”。要查看元素内容,需要使用Arrays.toString(),并且记得在文件开头导入java.util.Arrays:
importjava.util.Arrays;String[]arr={"张三","李四"};System.out.println(arr);// [Ljava.lang.String;@1b6d3586,看不到内容System.out.println(Arrays.toString(arr));// [张三, 李四]

2. 排序:sort()

排序,就是把容器里的元素按从小到大的顺序重新排列。静态数组和ArrayList都支持排序,调用排序方法后,原容器里的内容会被直接改变,方法本身不需要接收返回值。

静态数组:使用Arrays.sort()

Arrays是专门为数组提供辅助功能的工具类,排序前需要先在文件开头导入:

importjava.util.Arrays;

排序时直接把数组传进去即可,默认按从小到大(升序)排列:

int[]arr={3,1,2};Arrays.sort(arr);// 默认从小到大System.out.println(Arrays.toString(arr));// [1, 2, 3]
  • Arrays.sort(arr)没有返回值,调用结束后arr本身已经被重新排列;
  • 打印时仍然要使用Arrays.toString(),直接打印arr依然看不到元素内容。

ArrayList:使用Collections.sort()或list.sort()

ArrayList是集合,排序有两种常见写法,效果完全一样,默认都是升序。

第一种,使用集合工具类Collections,同样需要先导入:

importjava.util.Collections;Collections.sort(list);// 默认从小到大

第二种,直接调用ArrayList自带的sort()方法(Java 8 及以上可用),括号里传null表示按照“自然顺序”排序,也就是默认升序:

list.sort(null);// 与 Collections.sort(list) 等价,默认升序

完整示例如下:

importjava.util.ArrayList;importjava.util.Collections;ArrayList<Integer>list=newArrayList<>();list.add(3);list.add(1);list.add(2);Collections.sort(list);// 也可以写成 list.sort(null);System.out.println(list);// [1, 2, 3]

注意:ArrayList重写了toString(),所以排序完成后直接System.out.println(list)就能看到[1, 2, 3]这样的内容,不需要再做额外转换。

下期预告

虽然ArrayList已经帮我们实现了自动扩容,日常使用非常方便,但在一些比赛场景(例如蓝桥杯)中,还是要留意 JDK 版本带来的限制。

这里先纠正一个常见误解:并不是低版本 JDK 用不了ArrayList。ArrayList从很早期的 JDK 1.2 就已经存在,它本身不是新特性。

真正的差别在于:不同 JDK 版本下,能用的方法不一样。以排序为例:

list.sort(null);// JDK 8 及以上才能使用Collections.sort(list);// 老版本 JDK 也能使用

List接口自带的sort()方法是 Java 8 才加入的。如果比赛环境使用的是 JDK 7 或更早版本,写list.sort(null)会编译不通过,只能改用Collections.sort(list)。

蓝桥杯等比赛的历史环境普遍比较保守,很长一段时间使用的是 JDK 1.6、1.7、1.8 这样的老版本,而不是最新 JDK。因此,一些新语法、新方法在比赛中可能会“水土不服”。

正因如此,下一期我们会回到底层,用最基础的语法手写一个“自动扩容的数组”,不依赖某个新版本才有的特性。这样即使换到低版本比赛环境,代码也能稳定运行,同时还能真正搞懂ArrayList自动扩容背后的原理。

相关新闻

小型C编译器源码解析:从词法分析到代码生成的实现指南

小型C编译器源码解析:从词法分析到代码生成的实现指南

简介&#xff1a;这份资源是一套小型C编译器的完整源代码&#xff0c;面向希望深入理解编译原理、动手实践编译流程的开发者与计算机专业学生。它把词法分析、语法分析、语义分析、优化与代码生成等阶段落实为可读可改的代码&#xff0c;适合作为学习编译器内部运作的入门项目。…

2026/10/20 2:22:27 阅读更多 →
MAS 激活脚本完整指南:4 种方法免费激活 Windows 与 Office

MAS 激活脚本完整指南:4 种方法免费激活 Windows 与 Office

MAS 激活脚本完整指南&#xff1a;4 种方法免费激活 Windows 与 Office 【免费下载链接】Microsoft-Activation-Scripts Open-source Windows and Office activator featuring HWID, Ohook, TSforge, and Online KMS activation methods, along with advanced troubleshooting.…

2026/10/20 2:22:27 阅读更多 →
Java AI Agent生态全景 —— Spring AI vs LangGraph4j vs LangChain4j

Java AI Agent生态全景 —— Spring AI vs LangGraph4j vs LangChain4j

引子&#xff1a;一个后端团队的框架选型困局 你所在的Java后端团队接到一个需求&#xff1a;给现有的Spring Boot微服务集群加一个“智能运维助手”——它能查询服务健康状态、分析异常日志、执行简单的运维操作&#xff08;重启服务、扩容、回滚部署&#xff09;&#xff0c…

2026/10/20 2:21:27 阅读更多 →

最新新闻

大模型Skills应用实战:在Trae中把提示词变成可复用工作流

大模型Skills应用实战:在Trae中把提示词变成可复用工作流

这个系列写到第14篇&#xff0c;我聊点真正能提效的东西——大模型Skills应用。之前几篇要么在讲模型能力边界&#xff0c;要么在讲上下文工程&#xff0c;这次把视角落到一个具体场景&#xff1a;在Trae这款AI原生IDE里&#xff0c;怎么把Skill从"听说过"变成"…

2026/10/20 2:53:45 阅读更多 →
PC端缩放布局不崩:clamp()、视口字号、防撑破与Grid弹性收缩

PC端缩放布局不崩:clamp()、视口字号、防撑破与Grid弹性收缩

做 Web 开发的人&#xff0c;十有八九都被一个场景折腾过&#xff1a;你在 PC 上写了个布局&#xff0c;看着还挺满意。结果用户那边把浏览器窗口拉窄一点&#xff0c;或者按了Ctrl 滚轮缩放一下&#xff0c;整个页面瞬间就没法看了——侧边栏把内容挤成一团、文字溢出到屏幕外…

2026/10/20 2:53:45 阅读更多 →
OpenCode技能机制详解:从SKILL.md设计到团队共享实战

OpenCode技能机制详解:从SKILL.md设计到团队共享实战

1. 这份折腾的前提&#xff1a;OpenCode是什么&#xff0c;技能解决的是什么问题先说清楚我为什么会去研究这个&#xff0c;因为市面上叫"技能"或"Skills"的AI功能太多了。几个月前我还在终端里同时开着几个不同的AI编程工具&#xff0c;来回粘贴代码上下文…

2026/10/20 2:53:45 阅读更多 →
基于YOLOv5的动态增强遥感小目标检测方案

基于YOLOv5的动态增强遥感小目标检测方案

做遥感图像目标检测的时候&#xff0c;有一类问题特别让人头疼&#xff1a;高分辨率遥感图里目标很小、分布密集&#xff0c;通用检测模型跑起来一看&#xff0c;漏检的全是那些只有几十像素甚至十几个像素的小目标。我最初直接用现成的一套检测框架去处理&#xff0c;效果始终…

2026/10/20 2:53:45 阅读更多 →
BEV感知数据工程:数据集选择、标定时序与真值对齐

BEV感知数据工程:数据集选择、标定时序与真值对齐

做BEV感知这块时间久了&#xff0c;会有个特别深的感受&#xff1a;模型结构只是面子&#xff0c;数据工程才是里子。我接触过的几个环视检测项目里&#xff0c;模型选型、backbone替换、多尺度融合&#xff0c;加起来可能只花一周&#xff1b;真正耗进去一个多月的&#xff0c…

2026/10/20 2:53:45 阅读更多 →
Spring Boot公益服务平台开发实战:从数据库建模到答辩全流程指南

Spring Boot公益服务平台开发实战:从数据库建模到答辩全流程指南

最近帮几个学弟学妹把基于Spring Boot的公益服务平台从零到一完整搭了一遍&#xff0c;整个过程走了不少弯路&#xff0c;也沉淀了不少可以直接复用的经验。这类系统在课程设计和毕业设计里出现频率很高&#xff0c;一是业务场景贴近生活&#xff0c;二是功能边界清晰——用户注…

2026/10/20 2:52:44 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →