资讯动态

仓颉语言 ArrayList 详解:动态数组的构造、访问、增删改与扩容实践

发布时间:2026/10/15 3:04:22 来源:尧图企业网站定制
文档知识库教程OpenHarmony【免费下载链接】CangjieCorpus本仓库为仓颉编程语言语料库聚焦 仓颉编程语言 核心知识体系整合官方开发指南、API 文档、典型代码示例及语法规范等多维度资源经结构化处理与专业标注构建为支持 RAG检索增强生成技术 的高质量知识基座适配智能编码助手、学习辅助工具等应用开发需求。 欢迎开发者基于本语料库构建仓颉语言智能应用推动鸿蒙开发生态智能化升级项目地址https://gitcode.com/Cangjie/CangjieCorpus点击查看免费下载ArrayList 是仓颉编程语言标准库std.collection包提供的可变长度动态数组容器适合需要频繁增加和删除元素的场景。本文以官方指南 collection_arraylist.md 为主体结合标准库 collection 包类 API 与仓库内可运行示例系统讲解 ArrayList 的导入、构造、成员访问、增删改操作、切片以及容量管理策略。读完本文你将掌握 ArrayList 的完整使用方法并理解其底层扩容机制与性能取舍。导入与类型声明使用ArrayList类型需要先导入 collection 包import std.collection.*仓颉使用ArrayListT表示 ArrayList 类型其中T表示 ArrayList 的元素类型T可以是任意类型包括类、结构体、枚举、基础类型等。元素类型不相同的 ArrayList 属于不相同的类型它们之间不可以互相赋值以下写法是不合法的var a: ArrayListInt64 ... // ArrayList whose element type is Int64 var b: ArrayListString ... // ArrayList whose element type is String b a // Type mismatch编译报错从 API 文档可以看到ArrayListT实现了ListT接口ListT又继承自ReadOnlyListT与CollectionT因此它既具备只读列表的get、[]、first、last等能力也具备add、remove等修改能力具体声明见 collection 包类 API 中的 ArrayList 章节。与 Array 的定位差异Array 是长度不变的定长数组只支持修改元素、不支持增加和删除元素参见 数组类型而 ArrayList 既可以原地修改元素也可以原地增加和删除元素这是两者最本质的区别。构造 ArrayList 的五种方式仓颉中可以使用构造函数的方式构造一个指定的 ArrayList。官方指南给出了五种典型构造形式let a ArrayListString() // Created an empty ArrayList whose element type is String let b ArrayListString(100) // Created an ArrayList whose element type is String, and allocate a space of 100 let c ArrayListInt64([0, 1, 2]) // Created an ArrayList whose element type is Int64, containing elements 0, 1, 2 let d ArrayListInt64(c) // Use another Collection to initialize an ArrayList let e ArrayListString(2, {x: Int64 x.toString()}) // Created an ArrayList whose element type is String and size is 2. All elements are initialized by specified rule function结合标准库 API 文档可以补充更多细节ArrayListT()构造一个空 ArrayList初始容量为默认值16见 init() 定义。ArrayListT(capacity: Int64)构造初始容量为指定大小的 ArrayList。如果capacity小于 0会抛出IllegalArgumentException。ArrayListT(size: Int64, initElement: (Int64) - T)构造具有指定元素个数和初始化规则函数的 ArrayList例如ArrayListString(2, {x: Int64 x.toString()})会生成两个元素0、1size小于 0 时抛出IllegalArgumentException。ArrayListT(elements: CollectionT)用另一个相同元素类型的 Collection 初始化元素按集合迭代器返回的顺序排列因此ArrayListInt64(c)会复制c的全部元素。ArrayListT.of(elements: ArrayT)静态方法从数组构造 ArrayList例如ArrayListInt64.of([0, 1, 2])。访问 ArrayList 成员使用 for-in 遍历全部元素ArrayList实现了Iterable接口底层调用iterator()返回迭代器因此可以直接使用 for-in 循环遍历所有元素import std.collection.* main() { let list ArrayListInt64([0, 1, 2]) for (i in list) { println(The element is ${i}) } }编译并执行上面的代码会输出The element is 0 The element is 1 The element is 2关于 for-in 与迭代器的等价展开it.next()匹配Some/None可参见 Iterable 和 Collections 一节。需要注意collection 包的容器类都不支持并发修改在 for-in 遍历过程中对容器进行增删修改会抛出ConcurrentModificationException详见 collection 包异常说明。获取元素个数size 属性使用size属性可以获得 ArrayList 包含的元素个数import std.collection.* main() { let list ArrayListInt64([0, 1, 2]) if (list.size 0) { println(This is an empty arraylist) } else { println(The size of arraylist is ${list.size}) } }编译并执行上面的代码会输出The size of arraylist is 3下标访问单个元素访问指定位置的元素使用下标语法下标的类型必须是Int64。非空 ArrayList 的第一个元素总是从位置 0 开始可以访问 0 到size - 1的任意位置。使用负数或大于等于size的索引会触发运行时异常IndexOutOfBoundsExceptionlet a list[0] // a 0 let b list[1] // b 1 let c list[-1] // Runtime exceptions从源码结构看下标访问由operator func [](index: Int64): T运算符重载实现索引越界时抛出IndexOutOfBoundsException。另外标准库还提供了get(index: Int64): ?T方法——与下标语法不同get在索引越界时返回None而不是抛异常适合需要安全读取的场景仓库示例 sample_arraylist_get_set.md 展示了其配合getOrThrow()的用法var list ArrayListInt64([97, 100]) // list: [97, 100] list[1] 120 // 修改list: [97, 120] var b list.get(1) // 获取b 为 ?Int64 print(b${b.getOrThrow()}) // 输出 b120使用 Range 切片ArrayList 同样支持下标中传入RangeInt64进行切片切片返回的是一个全新的ArrayList对象与原 ArrayList 无引用关系range.step不等于 1 或范围无效时会抛出异常。相关语法细节与 Array 保持一致详见 数组类型Array 章节。切片运算符的底层定义为operator func [](range: RangeInt64): ArrayListT另外也存在独立的slice(range: RangeInt64): ArrayListT方法仓库示例 sample_arraylist_remove_clear_slice.md 演示了切片用法let r: RangeInt64 1..2 : 1 var sublist: ArrayListInt64 list.slice(r) // sublist: [2, 3]修改 ArrayList下标修改元素可以使用下标语法对某个位置的元素进行修改let list ArrayListInt64([0, 1, 2]) list[0] 3引用共享语义ArrayList 是引用类型作为表达式使用时不会拷贝副本同一个 ArrayList 实例的所有引用都会共享同样的数据。因此对 ArrayList 元素的修改会影响到该实例的所有引用let list1 ArrayListInt64([0, 1, 2]) let list2 list1 list2[0] 3 // list1 contains elements 3, 1, 2 // list2 contains elements 3, 1, 2若确实需要一份独立的副本可以调用clone()方法获得浅拷贝新 ArrayList 实例与原有对象互不影响元素引用仍共享。末尾追加元素使用add(element: T)将单个元素追加到末尾使用add(all!: CollectionT)一次性追加同元素类型 Collection例如 Array中的全部元素元素按迭代器顺序追加import std.collection.* main() { let list ArrayListInt64() list.add(0) // list contains element 0 list.add(1) // list contains elements 0, 1 let li [2, 3] list.add(all: li) // list contains elements 0, 1, 2, 3 }仓库示例 sample_arraylist_add.md 给出了容量预分配与批量追加组合的完整可运行代码import std.collection.* main() { var list: ArrayListInt64 ArrayListInt64(10) // 创建一个容量为 10 的 ArrayList var arr: ArrayInt64 [1, 2, 3] list.add(all: arr) // list: [1, 2, 3] list[1] 120 // list: [1, 120, 3] var b list.get(2) print(b${b.getOrThrow()},) // b3 list.add(12, at: 1) // list: [1, 12, 120, 3] var c list.get(2) print(c${c.getOrThrow()},) // c120 var arr1: ArrayInt64 [1,2,3] list.add(all: arr1, at: 1) // list: [1, 1, 2, 3, 12, 120, 3] var d list.get(2) print(d${d.getOrThrow()}) // d2 return 0 }运行结果b3,c120,d2指定位置插入元素add(element: T, at!: Int64)将单个元素插入到指定索引add(all!: CollectionT, at!: Int64)从指定位置开始插入整个 Collection。该索引处的元素和后面的元素会被挪后以腾出空间at超出范围时抛出IndexOutOfBoundsExceptionlet list ArrayListInt64([0, 1, 2]) // list contains elements 0, 1, 2 list.add(4, at: 1) // list contains elements 0, 4, 1, 2删除元素使用remove(at!: Int64)删除指定索引的元素被删除元素之后的元素会前移以填充空间返回值是被移除的元素let list ArrayListString([a, b, c, d]) // list contains the elements a, b, c, d list.remove(at: 1) // Delete the element at subscript 1, now the list contains elements a, c, d标准库还提供remove(range: RangeInt64)按范围批量删除、removeIf(predicate: (T) - Bool)按条件删除注意在 predicate 内增删改容器会抛出ConcurrentModificationException、以及clear()清空全部元素。仓库示例 sample_arraylist_remove_clear_slice.md 综合演示了这些操作import std.collection.* main() { var list: ArrayListInt64 ArrayListInt64([97, 100, 99]) // 变长参数列表的构造语法糖 list.remove(at: 1) // list: [97, 99] var b list.get(1) print(b${b.getOrThrow()},) // b99 list.clear() list.add(11) // list: [11] var arr: ArrayInt64 [1, 2, 3] list.add(all: arr, at: 0) // list: [1, 2, 3, 11] var g list.get(0) print(g${g.getOrThrow()},) // g1 let r: RangeInt64 1..2 : 1 var sublist: ArrayListInt64 list.slice(r) // sublist: [2, 3] var m sublist.get(0) print(m${m.getOrThrow()}) // m2 return 0 }运行结果b99,g1,m2增加 ArrayList 的大小扩容机制与 reserve每个 ArrayList 都需要特定数量的内存来保存其内容。当向 ArrayList 添加元素并且它开始超出其保留容量时ArrayList 会分配更大的内存区域并将其所有元素复制到新内存中。这种增长策略意味着触发重新分配内存的添加操作具有性能成本但随着 ArrayList 的保留内存变大这类重新分配发生的频率会越来越低。从标准库 API 的reserve(additional: Int64)定义可以看到具体的扩容规则当additional小于等于零时不发生扩容当剩余容量大于等于additional时不发生扩容当剩余容量小于additional时取「原始容量的 1.5 倍向下取整」与「additional 已使用容量」两者中的较大值进行扩容。若扩容后总容量超过Int64.Max会抛出OverflowException。如果预先知道大约需要添加多少个元素可以在添加之前预备足够的内存以避免中间重新分配从而提升性能表现import std.collection.* main() { let list ArrayListInt64(100) // Allocate space at once for (i in 0..100) { list.add(i) // Does not trigger reallocation of space } list.reserve(100) // Prepare more space for (i in 0..100) { list.add(i) // Does not trigger reallocation of space } }此外capacity属性可以随时查询 ArrayList 当前容量大小便于评估后续添加操作是否会触发扩容。其他常用能力与注意事项判等与包含ArrayListT在T : EquatableT时支持/!运算符两个数组相等指对应位置元素分别相等并可通过contains(element: T)判断是否包含指定元素。转字符串与转数组toString()输出形如[elem1, elem2, elem3]的字符串toArray()返回按正确顺序排列的ArrayT。遍历与排序iterator()返回按顺序遍历的迭代器。注意sort、sortDescending、sortBy等成员排序方法已标记为 deprecated官方建议改用 sort 包函数。线程安全collection 包提供的集合类型包括 ArrayList都不支持并发安全多线程场景请使用 collection.concurrent 包。结语ArrayList 是仓颉语言中面向「频繁增删查改」场景的动态数组容器其可变长度、引用共享语义、指定位置插入删除以及预分配容量等能力使它比定长的 Array 更灵活。结合标准库 类 API 文档 与仓库内的 add、get/set、remove/clear/slice 三份可运行示例读者可以快速将上述 API 应用到实际项目中。关于 ArrayList 与其他基础 CollectionArray、HashSet、HashMap的选择依据可进一步参考 基础 Collection 类型概述。赞分享文档知识库教程OpenHarmony【免费下载链接】CangjieCorpus本仓库为仓颉编程语言语料库聚焦 仓颉编程语言 核心知识体系整合官方开发指南、API 文档、典型代码示例及语法规范等多维度资源经结构化处理与专业标注构建为支持 RAG检索增强生成技术 的高质量知识基座适配智能编码助手、学习辅助工具等应用开发需求。 欢迎开发者基于本语料库构建仓颉语言智能应用推动鸿蒙开发生态智能化升级项目地址https://gitcode.com/Cangjie/CangjieCorpus点击查看免费下载相关推荐仓颉编程语言 ArrayList 详解动态数组的构造、访问、修改与扩容策略仓颉编程语言 ArrayList 详解动态数组的构造、访问、修改与扩容策略 ArrayListT 是仓颉标准库 std.collection 包提供的动态数文档编程语言仓颉语言 ArrayList 使用指南可变动态数组的构造、遍历、增删改与扩容优化仓颉语言 ArrayList 使用指南可变动态数组的构造、遍历、增删改与扩容优化 ArrayList 是仓颉标准库 std.collection 中提供的有序文档编程语言仓颉语言 HashMap 集合类型详解从构造、遍历访问到增删改的完整实践仓颉语言 HashMap 集合类型详解从构造、遍历访问到增删改的完整实践 HashMap 是仓颉语言 std.collection 包中用于存储键值对映射关系文档编程语言上一篇终极魔兽争霸3性能优化指南如何从60FPS突破到180FPS的完整教程下一篇终极指南如何用Ryzen SDT调试工具深度优化AMD处理器性能创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑