零基础鸿蒙应用开发第六节:复杂数据类型入门 —— 数组、元组与枚举
【学习目标】
- 理解数组的本质,掌握数组的创建、读取、修改和常用方法
- 理解元组的特性,掌握元组的创建与使用
- 理解枚举的作用,掌握枚举的定义、使用场景与核心优势
- 能清晰区分数组、元组与枚举的差异,根据业务场景选择使用
- 了解ArkTS线性容器类LinkedList/ArrayList,掌握其与原生数组的区别和使用场景
【学习重点】
- 数组创建优先使用
type[]字面量方式,下标从0开始且需避免越界 - 元组是固定长度、固定类型的有序集合,与数组的可变特性形成对比
- 数组常用方法中,区分“修改原数组”和“返回新数组”的类型
- 枚举用于定义命名常量集合,解决“魔法数字/字符串”问题,提升代码可读性
- LinkedList(双向链表)和ArrayList(动态数组)是鸿蒙封装的容器类,需根据性能需求选择
一、工程结构
本节我们将创建名为ArrayTupleEnumDemo的工程,基于鸿蒙5.0(API12)开发,使用DevEco Studio 6.0+工具,项目结构目录如下:
ArrayTupleEnumDemo
├── AppScope # 应用全局配置
├── entry # 主模块目录
│ ├── src
│ │ ├── main
│ │ │ ├── ets # ArkTS核心代码目录
│ │ │ │ ├── entryability # 应用入口能力
│ │ │ │ ├── pages # 页面组件目录
│ │ │ │ │ └── Index.ets # 核心页面
│ │ │ │ └── utils # 工具函数目录
│ │ │ │ └── ArrayTupleEnumTest.ets # 本节所有学习内容
│ │ │ ├── resources # 静态资源(图片/字符串等)
│ │ │ └── module.json5 # 模块配置文件
│ │ ├── ohosTest # 测试目录
│ │ └── test # 单元测试目录
│ ├── build-profile.json5 # 构建配置
│ ├── hvigorfile.ts # 构建脚本
│ └── oh-package.json5 # 依赖配置
├── hvigor # 构建工具依赖
└── oh_modules # 第三方依赖包
开发准备步骤
- 打开DevEco Studio,创建
ArrayTupleEnumDemo项目(选择Empty Ability模板,API12/鸿蒙5.0); - 在
src/main/ets目录下右键创建utils文件夹; - 选中
utils文件夹,右键创建ArrayTupleEnumTest.ets文件(封装所有学习函数); - 所有学习函数在
Index.ets的aboutToAppear生命周期中统一调用。
二、数组Array:有序的同类型数据容器
2.1 什么是数组?
数组是存储多个同类型数据的有序容器,可以把它想象成一排编号的储物柜:
- 每个储物柜有唯一的下标(索引)(从0开始,不是1)
- 每个储物柜里只能放同一类型的物品
- 储物柜的数量可以通过
push/pop等方法动态调整(底层实际是重新创建数组并复制数据)
2.2 数组的创建
两种创建数组的方式,字面量方式推荐,new Array()仅在特定场景使用。
| 创建方式 | 语法示例 | 特点说明 |
|---|---|---|
| T[] | const arr: number[] = [1,2,3] |
语法简洁、无歧义,支持类型标注,日常开发首选 |
| new Array() | const arr: Array<number> = new Array(1,2,3) |
语法繁琐,单个数字参数表示数组长度(易踩坑) |
代码示例:数组的创建
/**
* 测试数组的创建方式(字面量 vs new Array())
* 核心对比:字面量创建更直观,new Array()易产生歧义(单数字参数为长度)
*/
export function testArrayCreation(): void {
console.log(`\n========== 数组的创建 ==========`);
// 1. 字面量方式创建(推荐:语义清晰,无歧义)
const numArr: number[] = [10, 20, 30, 40]; // 数字数组(显式类型标注)
const strArr = ["苹果", "香蕉", "橙子"]; // 字符串数组(类型自动推断)
const emptyArr: number[] = []; // 空数组(后续可动态添加元素)
const nestedArr: number[][] = [[85, 92], [78, 95]]; // 嵌套数组(二维数组,数组的数组)
// 输出验证创建结果
console.log("数字数组:", numArr);
console.log("字符串数组:", strArr);
console.log("空数组:", emptyArr);
console.log("嵌套数组:", nestedArr);
// 2. new Array()方式(仅作对比,日常开发不推荐使用)
const arr1: Array<number> = new Array(1, 2, 3); // 多参数:参数直接作为数组元素
const arr2: Array<number> = new Array(3); // 单数字参数:表示数组长度(空占位符数组)
console.log("new Array(1,2,3):", arr1);
console.log("new Array(3):", arr2); // 输出:[](长度为3的空数组,控制台仅显示空数组标识)
console.log("访问arr2[0]:", arr2[0]); // 输出:undefined
// 避坑提示:创建单个数字元素的数组,必须使用字面量
const singleNumArr: number[] = [3]; // 正确:数组元素为数字3,长度1
const wrongArr: Array<number> = new Array(3); // 错误:长度为3的空数组,非元素3
}
运行效果
========== 数组的创建 ==========
数字数组: [10,20,30,40]
字符串数组: ["苹果","香蕉","橙子"]
空数组: []
嵌套数组: [[85,92],[78,95]]
new Array(1,2,3): [1,2,3]
new Array(3): []
访问arr2[0]: undefined
2.3 数组的读取(通过下标访问)
读取数组元素的核心是数组名[下标],下标从0开始,最后一个元素的下标是数组长度-1。
代码示例:数组的读取
/**
* 测试数组的读取操作(单层/嵌套数组 + 越界安全处理)
* 核心要点:下标从0开始,嵌套数组需多层下标,越界访问需前置判断
*/
export function testArrayRead(): void {
console.log(`\n========== 数组的读取 ==========`);
// 1. 单层数组读取(一维数组)
const fruits: string[] = ["苹果", "香蕉", "橙子"];
const firstFruit = fruits[0]; // 读取第一个元素(下标0)
const secondFruit = fruits[1]; // 读取第二个元素(下标1)
const lastFruit = fruits[fruits.length - 1]; // 读取最后一个元素(通用写法,适配数组长度变化)
// 输出读取结果
console.log("第一个水果:", firstFruit); // 输出:苹果
console.log("第二个水果:", secondFruit); // 输出:香蕉
console.log("最后一个水果:", lastFruit); // 输出:橙子
// 2. 嵌套数组读取(二维数组)
const classScores: number[][] = [[85, 92], [78, 95]]; // 外层数组:班级,内层数组:学生分数
const score1 = classScores[0][1]; // 外层下标0(第一个班级)→ 内层下标1(第二个学生分数)→ 92
const score2 = classScores[1][0]; // 外层下标1(第二个班级)→ 内层下标0(第一个学生分数)→ 78
console.log("外层0,内层1的分数:", score1); // 输出:92
console.log("外层1,内层0的分数:", score2); // 输出:78
// 3. 安全处理:数组越界访问(下标超出最大索引时的防护)
const targetIndex = 5; // fruits最大下标为2,5属于越界
// 推荐写法:先判断下标有效性,再读取,避免返回undefined
const fruit = targetIndex < fruits.length ? fruits[targetIndex] : "默认值(下标越界)";
console.log("读取结果(越界处理):", fruit); // 输出:默认值(下标越界)
}
运行效果
========== 数组的读取 ==========
第一个水果: 苹果
第二个水果: 香蕉
最后一个水果: 橙子
外层0,内层1的分数: 92
外层1,内层0的分数: 78
读取结果(越界处理): 默认值(下标越界)
2.4 数组的修改(通过下标赋值)
修改数组元素的格式为数组名[下标] = 新值,单层和嵌套数组的修改逻辑一致。
代码示例:数组的修改
/**
* 测试数组的修改操作(单层元素修改 + 嵌套数组增改)
* 核心要点:数组为引用类型,直接通过下标修改元素,嵌套数组需定位到内层下标
*/
export function testArrayModify(): void {
console.log(`\n========== 数组的修改 ==========`);
const fruits: string[] = ["苹果", "香蕉", "橙子"];
const classScores: number[][] = [[85, 92], [78, 95]];
// 1. 单层数组元素修改(直接通过下标赋值)
fruits[1] = "葡萄"; // 将下标1的"香蕉"修改为"葡萄"
console.log("修改后的水果数组:", fruits); // 输出:["苹果","葡萄","橙子"]
// 2. 嵌套数组修改(先添加内层数组,再修改内层元素)
classScores.push([60, 88]); // 向嵌套数组添加新的内层数组(第三个班级分数)
classScores[2][1] = 90; // 修改新添加的内层数组下标1的元素(88→90)
console.log("修改后的分数数组:", classScores); // 输出:[[85,92],[78,95],[60,90]]
}
运行效果
========== 数组的修改 ==========
修改后的水果数组: ["苹果","葡萄","橙子"]
修改后的分数数组: [[85,92],[78,95],[60,90]]
2.5 数组的常用方法(增删改查)
数组提供了常用方法来操作元素,分为修改原数组和返回新数组两类,新手需注意区分。
| 方法名 | 作用说明 | 是否修改原数组 |
|---|---|---|
push(item) |
在数组末尾添加一个/多个元素,返回新长度 | 是 |
pop() |
删除最后一个元素,返回被删除的元素 | 是 |
splice(start, delNum, ...add) |
指定位置增删改,返回被删元素 | 是 |
slice(start, end) |
截取元素,返回新数组 | 否 |
代码示例:数组常用方法
/**
* 测试数组的常用方法(修改原数组 vs 返回新数组)
* 核心区分:push/pop/splice修改原数组;slice返回新数组(原数组不变)
*/
export function testArrayMethods(): void {
console.log(`\n========== 数组的常用方法 ==========`);
// 1. 修改原数组的方法(会改变原数组内容/长度)
let nums: number[] = [1, 2, 3];
console.log("原数组:", nums); // 输出:[1,2,3]
// push:向数组末尾添加一个/多个元素,返回新数组长度
const newLength = nums.push(4, 5);
console.log("push后:", nums); // 输出:[1,2,3,4,5]
console.log("新长度:", newLength); // 输出:5
// pop:删除数组最后一个元素,返回被删除的元素
const popItem = nums.pop();
console.log("pop后:", nums); // 输出:[1,2,3,4]
console.log("被删除的元素:", popItem); // 输出:5
// splice:指定位置增/删/改元素,返回被删除的元素数组
// 参数说明:splice(起始下标, 删除数量, 新增元素1, 新增元素2...)
const spliceItems = nums.splice(1, 2, 6, 7); // 下标1开始删除2个元素,添加6、7
console.log("splice后:", nums); // 输出:[1,6,7,4]
console.log("被删除的元素:", spliceItems); // 输出:[2,3]
// 2. 不修改原数组的方法(返回新数组,原数组保持不变)
const nums2: number[] = [10, 20, 30, 40, 50];
// slice:截取指定范围元素,返回新数组(左闭右开,不包含结束下标)
const slice1 = nums2.slice(1, 3); // 截取下标1到3(不含3)→ [20,30]
const slice2 = nums2.slice(2); // 截取下标2到末尾 → [30,40,50]
console.log("原数组(slice不修改):", nums2); // 输出:[10,20,30,40,50]
console.log("slice(1,3):", slice1); // 输出:[20,30]
console.log("slice(2):", slice2); // 输出:[30,40,50]
}
运行效果
========== 数组的常用方法 ==========
原数组: [1,2,3]
push后: [1,2,3,4,5]
新长度: 5
pop后: [1,2,3,4]
被删除的元素: 5
splice后: [1,6,7,4]
被删除的元素: [2,3]
原数组(slice不修改): [10,20,30,40,50]
slice(1,3): [20,30]
slice(2): [30,40,50]
2.6 线性容器类:LinkedList与ArrayList
除了原生数组,ArkTS还提供了两个高频使用的容器类,底层分别基于双向链表和动态数组实现,适用于不同性能场景。
代码示例:LinkedList与ArrayList的使用
// 线性容器类必须在文件顶部导入
import { ArrayList, LinkedList } from "@kit.ArkTS";
/**
* 线性容器类:LinkedList(双向链表)、ArrayList(动态数组)
* 核心差异:LinkedList适合频繁增删,ArrayList适合频繁查询
*/
export function testHarmonyContainers(): void {
console.log(`\n========== LinkedList/ArrayList使用 ==========`);
// 1. LinkedList(双向链表):底层链表实现,头尾操作高效
const linkedList: LinkedList<number> = new LinkedList<number>();
try {
// 基础增删查
linkedList.add(100); // 向链表尾部添加元素
linkedList.add(200); // 继续向尾部添加
linkedList.insert(1, 300); // 在下标1的位置插入元素300
console.log("LinkedList首元素:", linkedList.getFirst()); // 获取链表第一个元素 → 100
console.log("LinkedList尾元素:", linkedList.getLast()); // 获取链表最后一个元素 → 200
console.log("LinkedList下标1元素:", linkedList.get(1)); // 获取下标1元素 → 300(需遍历链表)
// 链表头尾高效操作(核心优势)
linkedList.addFirst(50); // 向链表头部添加元素(O(1),无需遍历)
linkedList.add(250); // 向链表尾部添加元素(底层遍历到尾部,效率低于addFirst)
console.log("头尾添加后:", linkedList.convertToArray()); // 输出:[50,100,300,200,250]
// 链表删除操作
linkedList.removeFirst(); // 删除链表头部元素(O(1))
const lastValue = linkedList.getLast(); // 获取尾部元素
linkedList.remove(lastValue); // 删除尾部元素(需先获取值,再删除)
console.log("删除头尾后:", linkedList.convertToArray()); // 输出:[100,300,200]
console.log("LinkedList转原生数组:", linkedList.convertToArray()); // 输出:[100,300,200]
} catch (error) {
console.error("LinkedList操作异常:", error instanceof Error ? error.message : error);
}
// 2. ArrayList(动态数组):底层数组实现,查询高效,支持容量管理
const dynamicArr: ArrayList<number> = new ArrayList<number>();
try {
dynamicArr.add(10); // 添加元素到数组尾部
dynamicArr.add(20);
dynamicArr.add(30);
console.log("ArrayList初始元素:", dynamicArr.convertToArray()); // 输出:[10,20,30]
// 元素删除:按值删除、按下标删除
dynamicArr.remove(10); // 移除值为10的元素 → 剩余[20,30]
console.log("移除元素10后:", dynamicArr.convertToArray()); // 输出:[20,30]
dynamicArr.removeByIndex(1); // 移除下标1的元素30 → 剩余[20]
console.log("移除下标1元素后:", dynamicArr.convertToArray()); // 输出:[20]
// 安全访问:先确认元素存在,再通过下标访问
dynamicArr.add(40);
dynamicArr.add(50); // 补充元素,便于观察容量变化
console.log("ArrayList下标1元素:", dynamicArr[1]); // 输出:40(原生支持下标访问)
console.log("ArrayList当前容量:", dynamicArr.getCapacity()); // 输出:默认初始容量(如10)
// 容量管理(动态数组专属能力)
dynamicArr.increaseCapacityTo(20); // 手动扩容到20(提前预留空间,减少频繁扩容)
console.log("扩容后容量:", dynamicArr.getCapacity()); // 输出:20
dynamicArr.trimToCurrentLength(); // 释放冗余容量(容量=当前元素数量,节省内存)
console.log("优化后容量:", dynamicArr.getCapacity()); // 输出:3
// 转换为原生数组:便于使用标准数组方法
const nativeArr = dynamicArr.convertToArray();
console.log("ArrayList转原生数组:", nativeArr); // 输出:[20,40,50]
} catch (error) {
console.error("ArrayList操作异常:", error instanceof Error ? error.message : error);
}
}
运行效果
========== LinkedList/ArrayList使用 ==========
LinkedList首元素: 100
LinkedList尾元素: 200
LinkedList下标1元素: 300
头尾添加后: [50,100,300,200,250]
删除头尾后: [100,300,200]
LinkedList转原生数组: [100,300,200]
ArrayList初始元素: [10,20,30]
移除元素10后: [20,30]
移除下标1元素后: [20]
ArrayList下标1元素: 40
ArrayList当前容量: 10
扩容后容量: 20
优化后容量: 3
ArrayList转原生数组: [20,40,50]
核心对比
| 容器/数组类型 | 底层实现 | 内存结构 | 长度可变性 | 查询效率 | 增删效率 | 核心特性 | 核心适用场景 |
|---|---|---|---|---|---|---|---|
ArrayList<T> |
动态数组 | 连续内存块 | ✅(自动扩容50%/手动调整) | ⭐⭐⭐⭐(O(1) 索引直接访问) | ⭐(O(n) 中间增删需移动元素) | 基于数组实现,原生支持下标访问,可管理容量 | 高频读取、偶尔增删(如商品列表) |
LinkedList<T> |
双向链表 | 非连续内存(节点+指针) | ✅(按需创建节点) | ⭐(O(n) 需遍历链表) | ⭐⭐⭐⭐(O(1) 头尾增删仅修改指针) | 每个节点指向前后元素,头尾操作极致高效 | 头尾高频增删、双向遍历(如双向队列/缓存) |
Array<T> |
静态数组 | 连续内存块 | ❌(长度固定,扩容需重新创建) | ⭐⭐⭐⭐(O(1) 索引直接访问) | ❌(无原生动态增删,需splice模拟) | 基础有序容器,类型统一,语法简单 | 数据长度固定(如配置项、固定列表) |
提示:数组还有很多内置的高级用法(如
filter、map、reduce等迭代方法),基础阶段前期我们主要以掌握上述核心增删改查方法为主,这些高级用法会在后续的进阶章节中结合业务场景详细讲解。
三、元组(Tuple):固定长度的异类型有序集合
3.1 什么是元组?
元组是ArkTS(TypeScript)中特有的数据类型,是固定长度、固定类型的有序集合,可以把它想象成“定制化的储物柜”:
- 每个储物柜有固定的类型(可以是不同类型,比如第一个放数字,第二个放字符串)
- 语法上支持
push添加元素,但会破坏元组的固定长度特性(类型层面不推荐) - 下标从0开始,访问方式和数组一致
3.2 元组的创建与使用
代码示例
/**
* 测试元组的核心操作:创建、访问、修改
* 核心特性:元组是固定长度、固定类型顺序的数组,类型校验严格
*/
export function testTupleBasic(): void {
console.log(`\n========== 元组的核心操作 ==========`);
// 1. 元组创建:必须显式标注类型(固定长度+类型顺序)
const userInfo: [number, string, boolean] = [1001, "张三", true]; // 编号(数字)、姓名(字符串)、VIP(布尔)
const point: [number, number] = [100, 200]; // 二维坐标(x轴数字,y轴数字)
const color: readonly [number, number, number] = [255, 0, 0]; // 只读元组:元素不可修改(RGB颜色值)
console.log("用户信息元组:", userInfo); // 输出:[1001,"张三",true]
console.log("坐标元组:", point); // 输出:[100,200]
console.log("颜色元组(只读):", color); // 输出:[255,0,0]
// 2. 元组访问:通过下标访问,类型与定义时一致
const userId = userInfo[0]; // 数字类型
const userName = userInfo[1]; // 字符串类型
console.log("用户编号:", userId); // 输出:1001
console.log("用户姓名:", userName); // 输出:张三
// 3. 元组修改:仅能修改对应下标元素,且类型必须匹配
userInfo[2] = false; // 布尔类型修改为false,符合类型定义
console.log("修改后的VIP状态:", userInfo[2]); // 输出:false
// 错误操作示例(取消注释会编译报错)
// userInfo[1] = 123; // 报错:下标1要求string类型,不能赋值number
// color[0] = 200; // 报错:readonly元组的属性为只读,无法修改
}
运行效果
========== 元组的核心操作 ==========
用户信息元组: [1001,"张三",true]
坐标元组: [100,200]
颜色元组(只读): [255,0,0]
用户编号: 1001
用户姓名: 张三
修改后的VIP状态: false
3.3 数组与元组的核心区别
| 特性 | 数组 | 元组 |
|---|---|---|
| 长度 | 可变(可增删元素) | 设计为固定长度(语法支持push但不推荐) |
| 元素类型 | 必须同类型 | 可以不同类型(固定顺序) |
| 类型标注 | 可省略(自动推断) | 必须显式标注(readonly元组也需标注) |
| 使用场景 | 存储多个同类型数据 | 存储固定结构的不同类型数据(如坐标、用户信息) |
四、枚举(Enum):命名常量的集合
4.1 为什么需要枚举?
在开发中,我们经常会遇到一组固定的常量值(比如:性别、订单状态、颜色)。如果直接用数字或字符串表示,会存在可读性差、易出错的问题。枚举类型能为一组常量赋予有意义的名称,让代码更清晰、更健壮。
4.2 枚举的创建与使用
代码示例
/**
* 测试枚举的定义与使用:数字枚举、字符串枚举、常量枚举
* 核心价值:将魔法值封装为具名常量,提升代码可读性和可维护性
*/
export function testEnumBasic(): void {
console.log(`\n========== 枚举的核心操作 ==========`);
// 1. 数字枚举:默认从0开始递增,支持反向查找(值→名)
enum Gender {
Male, // 默认值0
Female // 默认值1
}
console.log("男性的枚举值:", Gender.Male); // 输出:0
console.log("值为1的枚举名:", Gender[1]); // 输出:Female(数字枚举专属反向查找)
// 枚举作为类型标注:变量仅能赋值枚举成员
let userGender: Gender = Gender.Male;
userGender = Gender.Female; // 正确:赋值枚举成员
// userGender = 2; // 错误:2不是Gender枚举的有效成员
// 2. 字符串枚举(推荐使用):语义更清晰,无反向查找
enum OrderStatus {
Pending = "待支付",
Paid = "已支付",
Canceled = "已取消"
}
console.log("待支付状态:", OrderStatus.Pending); // 输出:待支付
console.log("已支付状态:", OrderStatus.Paid); // 输出:已支付
// 字符串枚举类型标注
let orderStatus: OrderStatus = OrderStatus.Pending;
orderStatus = OrderStatus.Canceled; // 正确
// orderStatus = "已完成"; // 错误:"已完成"不是OrderStatus的有效成员
// 3. 常量枚举:编译时直接替换为常量值,优化性能,无反向查找
const enum Color {
Red = "红色",
Green = "绿色",
Blue = "蓝色"
}
let fontColor: Color = Color.Red;
console.log("字体颜色:", fontColor); // 输出:红色
// console.log(Color["红色"]); // 错误:常量枚举不支持反向查找(仅普通数字枚举支持)
}
运行效果
========== 枚举的核心操作 ==========
男性的枚举值: 0
值为1的枚举名: Female
待支付状态: 待支付
已支付状态: 已支付
字体颜色: 红色
4.3 数组、元组与枚举的核心区别
| 特性 | 数组 | 元组 | 枚举 |
|---|---|---|---|
| 本质 | 同类型值的可变集合 | 多类型值的固定集合(语法支持push) | 命名常量的不可变集合 |
| 长度 | 可变 | 设计为固定(语法支持push但不推荐) | 固定(常量数量固定) |
| 元素可修改 | 是 | 是(类型匹配时) | 否(枚举常量值不可修改) |
| 使用场景 | 存储动态的同类型数据 | 存储固定结构的多类型数据 | 存储固定的常量值(状态、类型) |
4.4 新手易错点总结
- 数组下标越界:始终确保访问的下标 < 数组长度,推荐用
arr.length - 1获取最后一个元素; - new Array() 陷阱:
new Array(3)是创建长度为3的空数组,而非元素为3的数组,新手优先用[3]; - 元组的push误用:元组设计为固定长度,语法支持push但会破坏类型约束,开发中禁止使用;
- import 位置错误:ArkTS中
import必须放在文件顶部,不能在函数/方法内; - 枚举反向查找误区:只有数字枚举支持反向查找(
Gender[0] = 'Male'),字符串枚举/常量枚举不支持; - LinkedList下标访问性能:LinkedList的
get(index)需遍历链表,频繁查询请改用ArrayList/原生数组,优先使用头尾操作方法。
五、完整可运行代码(Index.ets)
// pages/Index.ets
// 1. 导入工具类的所有测试函数
import {
testArrayCreation,
testArrayRead,
testArrayModify,
testArrayMethods,
testHarmonyContainers,
testTupleBasic,
testEnumBasic
} from '../utils/ArrayTupleEnumTest';
@Entry
@Component
struct Index {
// 生命周期方法:统一调用所有测试方法
aboutToAppear(): void {
testArrayCreation(); // 数组创建
testArrayRead(); // 数组读取
testArrayModify(); // 数组修改
testArrayMethods(); // 数组常用方法
testHarmonyContainers(); //线性容器LinkedList/ArrayList
testTupleBasic(); // 元组核心操作
testEnumBasic(); // 枚举核心操作
}
build() {
Column() {
Text("数组、元组与枚举基础")
.fontSize(30)
.fontWeight(FontWeight.Bold)
Text("运行日志请查看控制台")
.fontSize(16)
.marginTop(20)
.fontColor(Color.Grey)
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center);
}
}
六、内容总结
- 数组/容器类选型核心:
- 连续内存(ArrayList/Array)查询快,非连续内存(LinkedList)头尾增删快;
- ArrayList/LinkedList 支持动态调整长度,Array 长度固定;
- 查多用 ArrayList/Array,头尾高频增删多用 LinkedList,数据固定用 Array;
- 元组使用原则:固定长度/类型的异类型集合,需显式标注类型,
readonly元组不可修改,禁用push避免破坏类型约束; - 枚举最佳实践:优先使用字符串枚举解决“魔法值”问题,常量枚举优化性能但不支持反向查找;
- 核心避坑点:数组访问先判长度、
new Array()慎用、元组禁用push、LinkedList避免频繁下标查询。
七、代码仓库
- 工程名称:ArrayTupleEnumDemo
- 仓库地址:https://gitee.com/juhetianxia321/harmony-os-code-base.git
八、下节预告
下一节将进入分支语句(if-else、switch),重点包括:
- 理解流程控制的核心作用,掌握
if-else分支语句的语法与嵌套使用场景。 - 掌握
switch语句的语法与break关键字的作用,理解switch与if-else的适用场景差异。 - 掌握三元运算符的使用,区分三元运算符与
if-else的使用场景。 - 能结合业务场景使用分支语句处理条件判断(如成绩等级判断、订单状态处理)。
浙公网安备 33010602011771号