零基础鸿蒙应用开发第六节:复杂数据类型入门 —— 数组、元组与枚举

零基础鸿蒙应用开发学习计划表

【学习目标】

  1. 理解数组的本质,掌握数组的创建、读取、修改和常用方法
  2. 理解元组的特性,掌握元组的创建与使用
  3. 理解枚举的作用,掌握枚举的定义、使用场景与核心优势
  4. 能清晰区分数组、元组与枚举的差异,根据业务场景选择使用
  5. 了解ArkTS线性容器类LinkedList/ArrayList,掌握其与原生数组的区别和使用场景

【学习重点】

  1. 数组创建优先使用type[]字面量方式,下标从0开始且需避免越界
  2. 元组是固定长度、固定类型的有序集合,与数组的可变特性形成对比
  3. 数组常用方法中,区分“修改原数组”和“返回新数组”的类型
  4. 枚举用于定义命名常量集合,解决“魔法数字/字符串”问题,提升代码可读性
  5. 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               # 第三方依赖包

开发准备步骤

  1. 打开DevEco Studio,创建ArrayTupleEnumDemo项目(选择Empty Ability模板,API12/鸿蒙5.0);
  2. src/main/ets目录下右键创建utils文件夹;
  3. 选中utils文件夹,右键创建ArrayTupleEnumTest.ets文件(封装所有学习函数);
  4. 所有学习函数在Index.etsaboutToAppear生命周期中统一调用。

二、数组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模拟) 基础有序容器,类型统一,语法简单 数据长度固定(如配置项、固定列表)

提示:数组还有很多内置的高级用法(如filtermapreduce等迭代方法),基础阶段前期我们主要以掌握上述核心增删改查方法为主,这些高级用法会在后续的进阶章节中结合业务场景详细讲解。


三、元组(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 新手易错点总结

  1. 数组下标越界:始终确保访问的下标 < 数组长度,推荐用 arr.length - 1 获取最后一个元素;
  2. new Array() 陷阱new Array(3) 是创建长度为3的空数组,而非元素为3的数组,新手优先用 [3]
  3. 元组的push误用:元组设计为固定长度,语法支持push但会破坏类型约束,开发中禁止使用;
  4. import 位置错误:ArkTS中 import 必须放在文件顶部,不能在函数/方法内;
  5. 枚举反向查找误区:只有数字枚举支持反向查找(Gender[0] = 'Male'),字符串枚举/常量枚举不支持;
  6. 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);
  }
}

六、内容总结

  1. 数组/容器类选型核心
    • 连续内存(ArrayList/Array)查询快,非连续内存(LinkedList)头尾增删快;
    • ArrayList/LinkedList 支持动态调整长度,Array 长度固定;
    • 查多用 ArrayList/Array,头尾高频增删多用 LinkedList,数据固定用 Array;
  2. 元组使用原则:固定长度/类型的异类型集合,需显式标注类型,readonly元组不可修改,禁用push避免破坏类型约束;
  3. 枚举最佳实践:优先使用字符串枚举解决“魔法值”问题,常量枚举优化性能但不支持反向查找;
  4. 核心避坑点:数组访问先判长度、new Array() 慎用、元组禁用push、LinkedList避免频繁下标查询。

七、代码仓库


八、下节预告

下一节将进入分支语句(if-else、switch),重点包括:

  1. 理解流程控制的核心作用,掌握if-else分支语句的语法与嵌套使用场景。
  2. 掌握switch语句的语法与break关键字的作用,理解switchif-else的适用场景差异。
  3. 掌握三元运算符的使用,区分三元运算符与if-else的使用场景。
  4. 能结合业务场景使用分支语句处理条件判断(如成绩等级判断、订单状态处理)。
posted @ 2026-01-16 17:35  鸿蒙-散修  阅读(1)  评论(0)    收藏  举报