📚鸿蒙开发往期学习笔录✒️:
✒️ 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~
✒️ 鸿蒙应用开发与鸿蒙系统开发哪个更有前景?
✒️ 嵌入式开发适不适合做鸿蒙南向开发?看完这篇你就了解了~
✒️ 对于大前端开发来说,转鸿蒙开发究竟是福还是祸?
✒️ 鸿蒙岗位需求突增!移动端、PC端、IoT到底该怎么选?
✒️ 记录一场鸿蒙开发岗位面试经历~
✒️ 持续更新中……
概述
容器类库,用于存储各种数据类型的元素,并具备一系列处理数据元素的方法,作为纯数据结构容器来使用具有一定的优势。
容器类采用了类似静态语言的方式来实现,并通过对存储位置以及属性的限制,让每种类型的数据都能在完成自身功能的基础上去除冗余逻辑,保证了数据的高效访问,提升了应用的性能。
当前提供了线性和非线性两类容器。线性类容器底层通过数组实现,非线性类容器底层通过hash或者红黑树实现。 线性容器 和 非线性容器 都是非多线程安全的。
线性容器
线性容器实现能按顺序访问的数据结构,其底层主要通过数组实现,包括ArrayList、Vector、List、LinkedList、Deque、Queue、Stack七种。
线性容器,充分考虑了数据访问的速度,运行时(Runtime)通过一条字节码指令就可以完成增、删、改、查等操作。
各线性容器类型特征对比
类名 | 特征及建议使用场景 |
---|---|
ArrayList | 动态数组,占用一片连续的内存空间。需要频繁读取元素时推荐使用。 |
List | 单向链表,占用的空间可以不连续。需要频繁的插入删除元素且需要使用单向链表时推荐使用。 |
LinkedList | 双向链表,占用的空间可以不连续。需要频繁的插入删除元素且需要使用双向链表时推荐使用。 |
Deque | 双端队列,可以从容器头尾进行进出元素操作,占用一片连续的内存空间。需要频繁访问、操作头尾元素时推荐使用。 |
Queue | 队列,从容器尾部插入元素,从容器头部弹出元素,占用一片连续的内存空间。一般符合先进先出的场景可以使用。 |
Stack | 栈,只能从容器的一端进行插入删除操作,占用一片连续的内存空间。一般符合先进后出的场景可以使用。 |
Vector | 动态数组,占用一片连续的内存空间。该类型已不再维护,推荐使用ArrayList。 |
ArrayList
ArrayList 即动态数组,可用来构造全局的数组对象。 当需要频繁读取集合中的元素时,推荐使用ArrayList。
ArrayList依据泛型定义,要求存储位置是一片连续的内存空间,初始容量大小为10,并支持动态扩容,每次扩容大小为原始容量的1.5倍。
ArrayList进行增、删、改、查操作的常用API如下:
操作 | 方法 | 描述 |
---|---|---|
增加元素 | add(element: T) | 在数组尾部增加一个元素。 |
增加元素 | insert(element: T, index: number) | 在指定位置插入一个元素。 |
访问元素 | arr[index: number] | 获取指定index对应的value值,通过指令获取保证访问速度。 |
访问元素 | forEach(callbackFn: (value: T, index?: number, arrlist?: ArrayList) => void, thisArg?: Object) | 访问整个ArrayList容器的元素。 |
访问元素 | Symbol.iterator:IterableIterator | 创建迭代器以进行数据访问。 |
修改元素 | arr[index] = xxx | 修改指定index位置对应的value值。 |
删除元素 | remove(element: T) | 删除第一个匹配到的元素。 |
删除元素 | removeByRange(fromIndex: number, toIndex:number) | 删除指定范围内的元素。 |
List
List 可用来构造一个单向链表对象,即只能通过头结点开始访问到尾节点。List依据泛型定义,在内存中的存储位置可以是不连续的。
List和 LinkedList 相比,LinkedList是双向链表,可以快速地在头尾进行增删,而List是单向链表,无法双向操作。
当需要频繁的插入删除元素,并且需要使用单向链表时,推荐使用List高效操作。
可以通过get/set等接口对存储的元素进行修改,List进行增、删、改、查操作的常用API如下:
操作 | 方法 | 描述 |
---|---|---|
增加元素 | add(element: T) | 在数组尾部增加一个元素。 |
增加元素 | insert(element: T, index: number) | 在指定位置插入一个元素。 |
访问元素 | get(index: number) | 获取指定index位置对应的元素。 |
访问元素 | list[index: number] | 获取指定index位置对应的元素,但会导致未定义结果。 |
访问元素 | getFirst() | 获取第一个元素。 |
访问元素 | getLast() | 获取最后一个元素。 |
访问元素 | getIndexOf(element: T) | 获取第一个匹配指定元素的位置。 |
访问元素 | getLastIndexOf(element: T) | 获取最后一个匹配指定元素的位置。 |
访问元素 | forEach(callbackfn: (value:T, index?: number, list?: List)=> void,thisArg?: Object) | 遍历访问整个List容器的元素。 |
访问元素 | Symbol.iterator:IterableIterator | 创建迭代器以进行数据访问。 |
修改元素 | set(index:number, element: T) | 修改指定index位置的元素值为element。 |
修改元素 | list[index] = element | 修改指定index位置的元素值为element,但会导致未定义结果。 |
修改元素 | replaceAllElements(callbackFn:(value: T,index?: number,list?: List)=>T,thisArg?: Object) | 对List内元素进行逐个替换。 |
删除元素 | remove(element: T) | 删除第一个匹配到的元素。 |
删除元素 | removeByIndex(index:number) | 删除index位置对应的元素。 |
LinkedList
LinkedList 可用来构造一个双向链表对象,可以在某一节点向前或者向后遍历List。LinkedList依据泛型定义,在内存中的存储位置可以是不连续的。
LinkedList和 List 相比,LinkedList是双向链表,可以快速地在头尾进行增删,而List是单向链表,无法双向操作。
LinkedList和 ArrayList 相比,插入数据效率LinkedList优于ArrayList,而查询效率ArrayList优于LinkedList。
当需要频繁的插入删除元素,并且需要使用双向链表时,推荐使用LinkedList高效操作。
可以通过get/set等接口对存储的元素进行修改,LinkedList进行增、删、改、查操作的常用API如下:
操作 | 方法 | 描述 |
---|---|---|
增加元素 | add(element: T) | 在数组尾部增加一个元素。 |
增加元素 | insert(element: T, index: number) | 在指定位置插入一个元素。 |
访问元素 | get(index: number) | 获取指定index位置对应的元素。 |
访问元素 | list[index: number] | 获取指定index位置对应的元素,但会导致未定义结果。 |
访问元素 | getFirst() | 获取第一个元素。 |
访问元素 | getLast() |