C# 交错数组(建议收藏)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观
前言
在编程中,数组是一种基础且重要的数据结构。但当需要处理的数据规模或形状不规则时,传统的矩形数组(如二维数组)可能无法满足需求。此时,C# 交错数组(Jagged Array)便展现出其独特优势。它允许每个子数组的长度不同,适用于表格数据、分层结构或不规则形状的场景。本文将从基础概念、实现方法到实际案例,系统讲解交错数组的使用技巧与核心原理,帮助开发者高效管理复杂数据。
什么是 C# 交错数组?
定义与特点
C# 交错数组是一种“数组的数组”,即每个元素本身也是一个数组。其核心特点是:
- 子数组长度可变:同一层级的子数组可以有不同的长度。
- 内存分配灵活:每个子数组独立分配内存,避免矩形数组因固定长度导致的内存浪费。
- 访问效率高:通过双重索引快速定位元素,如
array[i][j]
。
形象比喻:可以将交错数组想象为一个图书馆的书架,每一层书架(子数组)存放的书籍数量不同,但整体通过书架的编号(主索引)和书籍的顺序(子索引)来定位。
与矩形数组的对比
现有数组类型 | 定义方式 | 元素存储方式 | 适用场景 |
---|---|---|---|
矩形数组 | int[,] | 固定行列长度 | 规则表格、棋盘等 |
交错数组 | int[][] | 子数组长度可变 | 不规则数据、分层结构 |
例如,若要存储某公司不同部门的员工数量,若部门人数不固定,使用交错数组更合理:
int[][] departmentMembers = {
new int[] {5, 3}, // 技术部(小组1有5人,小组2有3人)
new int[] {8}, // 销售部(仅1个小组)
new int[] {2, 4, 6} // 财务部(3个小组)
};
如何创建与初始化交错数组?
基础语法与步骤
创建交错数组需分两步:
- 声明主数组:定义主数组的类型和长度。
- 初始化子数组:为每个主数组元素分配独立的子数组。
示例1:直接初始化
// 声明主数组(长度为3)
int[][] jaggedArray = new int[3][];
// 初始化每个子数组
jaggedArray[0] = new int[] {1, 2, 3}; // 子数组长度为3
jaggedArray[1] = new int[] {4, 5}; // 子数组长度为2
jaggedArray[2] = new int[] {6}; // 子数组长度为1
示例2:单行初始化(更简洁)
int[][] jaggedArray = new int[][] {
new int[] {10, 20},
new int[] {30, 40, 50},
new int[] {60}
};
动态扩展子数组
若需在运行时动态调整子数组的长度,可使用 Array.Resize
或重新赋值:
// 原子数组长度为2
jaggedArray[0] = new int[] {1, 2};
// 动态扩展为长度3
Array.Resize(ref jaggedArray[0], 3);
jaggedArray[0][2] = 3; // 新元素赋值
访问与遍历交错数组
元素访问
通过双重索引访问元素,如 array[主索引][子索引]
:
int value = jaggedArray[1][2]; // 获取第二个子数组的第三个元素(50)
安全性注意事项
由于子数组长度不固定,需避免越界访问。建议使用 GetLength
或循环条件判断:
// 获取子数组长度
int subLength = jaggedArray[i].Length;
// 安全遍历子数组
for (int j = 0; j < subLength; j++) {
Console.WriteLine(jaggedArray[i][j]);
}
多重循环遍历
使用嵌套循环遍历整个数组:
for (int i = 0; i < jaggedArray.Length; i++) {
for (int j = 0; j < jaggedArray[i].Length; j++) {
Console.Write(jaggedArray[i][j] + " ");
}
Console.WriteLine();
}
输出结果:
10 20
30 40 50
60
实际案例:销售数据的动态管理
假设某公司需要记录不同月份的销售数据,且每月的周数不同(如闰年或非整月统计)。使用交错数组可灵活存储:
double[][] monthlySales = new double[12][];
// 初始化各月数据(假设数据不规则)
monthlySales[0] = new double[] { 1500, 1800, 2100 }; // 1月3周数据
monthlySales[1] = new double[] { 1700, 1600, 1900, 2000 }; // 2月4周数据
// ... 其他月份类似
// 计算某月总销售额
int monthIndex = 0;
double total = 0;
foreach (double sale in monthlySales[monthIndex]) {
total += sale;
}
Console.WriteLine($"1月总销售额:{total}"); // 输出 5400
性能与注意事项
内存分配优势
交错数组的内存分配更高效:
- 矩形数组需预先分配所有元素的空间,即使某些行未被使用。
- 交错数组仅占用实际子数组的内存,适合不规则数据。
访问速度
由于每个子数组独立存储,访问时需两次内存寻址(先主数组,再子数组),速度略低于矩形数组。但在数据不规则场景下,这种牺牲是值得的。
典型错误与解决
-
空引用异常:若未初始化子数组直接访问。
// 错误示例 int[][] arr = new int[3][]; Console.WriteLine(arr[0][0]); // 抛出NullReferenceException
解决方法:确保每个子数组已初始化。
-
索引越界:访问超出子数组长度的元素。
解决方法:使用Length
属性验证索引范围。
结论
C# 交错数组为处理不规则数据提供了灵活且高效的解决方案。通过理解其“数组的数组”特性,开发者可以更自如地应对分层结构、动态数据集等复杂场景。无论是销售统计、游戏地图设计,还是科学计算中的不规则网格,交错数组都能通过其动态扩展能力和内存管理优势,成为代码优化的关键工具。
掌握交错数组的核心在于:
- 熟练初始化与访问语法;
- 注意子数组的独立性与安全性;
- 根据实际需求选择交错数组或矩形数组。
通过本文的案例与代码示例,相信读者已能将 C# 交错数组 应用于实际项目中,提升数据管理的灵活性与效率。