(以下内容来自开发者分享,不代表 OpenHarmony 项目群工作委员会观点)


刘鑫

容器类,顾名思义就是存储的类,用于存储各种数据类型的元素,并具备一系列处理数据元素的方法。在 ArkUI 开发框架中,容器类采用了类似静态的语言来实现,并通过 NAPI 框架对外提供。通过对存储位置以及属性的限制,让每种类型的数据都能在完成自身功能的基础上剪除冗余分支,保证了数据的高效访问,提升了应用的性能。

本期,我们将为大家介绍 ArkUI 开发框架中容器类的各种类型以及相关 API 的使用。

一、容器类API介绍

在 ArkUI 开发框架中,提供了线性和非线性两类容器类,共 14 种,每种容器都有自身的特性及使用场景。下面,我们将为大家一一道来。

1.1线性容器类

线性容器类底层主要通过数组实现,包括 ArrayList、Vector、List、LinkedList、Deque、Queue、Stack 七种。线性容器类 API,充分考虑了数据访问的速度,实现了运行时(Runtime)通过一条指令就可以完成增删改查等操作。

1.1.1 ArrayList

ArrayList 即动态数组,可用来构造全局的数组对象。ArrayList 依据泛型定义,要求存储位置是一片连续的内存空间,初始容量大小为 10,并支持动态扩容,每次扩容大小为原始容量的 1.5 倍。ArrayList 进行增、删、改、查操作的相关 API 如下:

1.1.2 Vector

Vector 是指连续存储结构,可用来构造全局的数组对象。Vector 依据泛型定义,要求存储位置是一片连续的内存空间,初始容量大小为 10,并支持动态扩容,每次扩容大小为原始容量的2倍。

由于 Vector 扩容速度高于 ArrayList,所以适用于数据添加比较频繁的场景。Vector 在支持操作符访问的基础上,还增加了 get/set 接口,提供更为完善的校验及容错机制,满足用户不同场景下的需求。Vector 进行增、删、改、查操作的相关 API 如下:

1.1.3 List

List 可用来构造一个单向链表对象,即只能通过头结点开始访问到尾节点。List 依据泛型定义,在内存中的存储位置可以是不连续的。

可以通过 get/set 等接口对存储的元素进行修改,List 进行增、删、改、查操作的相关 API 如下:

1.1.4 LinkedList

LinkedList 可用来构造一个双向链表对象,可以在某一节点向前或者向后遍历 List。LinkedList 依据泛型定义,在内存中的存储位置可以是不连续的。

可以通过 get/set 等接口对存储的元素进行修改,LinkedList 进行增、删、改、查操作的相关 API 如下:

1.1.5 Queue

Queue 可用来构造队列对象,存储元素遵循先进先出的规则。Queue 依据泛型定义,要求存储位置是一片连续的内存空间,初始容量大小为 8,并支持动态扩容,每次扩容大小为原始容量的 2 倍。Queue 底层采用循环队列实现,入队及出队操作效率都比较高。Queue 进行增、删、改、查操作的相关 API 如下:

1.1.6 Deque

Deque 可用来构造双端队列对象,存储元素遵循先进先出的规则,双端队列可以分别从对头或者队尾进行访问。Deque 依据泛型定义,要求存储位置是一片连续的内存空间,其初始容量大小为 8,并支持动态扩容,每次扩容大小为原始容量的 2 倍。Deque 底层采用循环队列实现,入队及出队操作效率都比较高。Deque 进行增、删、改、查操作的相关 API 如下:

1.1.7 Stack

Stack 可用来构造栈对象,存储元素遵循后进先出的规则。Stack 依据泛型定义,要求存储位置是一片连续的内存空间,初始容量大小为 8,并支持动态扩容,每次扩容大小为原始容量的 1.5 倍。Stack 底层基于数组实现,入栈出栈均从数组的一端操作,Stack 进行增、删、改、查操作的相关 API 如下:

1.2非线性容器类

非线性容器类底层通过 hash 或者红黑树实现,包括 HashMap、HashSet、TreeMap、TreeSet、LightWeightMap、LightWeightSet、PlainArray 七种。非线性容器类中的 key 及 value 的类型均满足 ECMA 标准。

1.2.1 HashMap

HashMap 可用来存储具有关联关系的 key-value 键值对集合,存储元素中 key 是唯一的,每个 key 会对应一个 value 值。HashMap 依据泛型定义,集合中通过 key 的 hash 值确定其存储位置,从而快速找到键值对。HashMap 的初始容量大小为 16,并支持动态扩容,每次扩容大小为原始容量的 2 倍。HashMap 底层基于 HashTable 实现,冲突策略采用链地址法。HashMap 进行增、删、改、查操作的相关 API 如下:

1.2.2 HashSet

HashSet 可用来存储一系列值的集合,存储元素中 value 是唯一的。依据泛型定义。集合中通过 value 的 hash 值确定其存储位置,从而快速找到该值。HashSet 初始容量大小为 16,支持动态扩容,每次扩容大小为原始容量的 2 倍。value 的类型满足 ECMA 标准中要求的类型。HashSet 底层基于 HashTable 实现,冲突策略采用链地址法。HashSet 进行增、删、改、查操作的相关 API 如下:

1.2.3 TreeMap

TreeMap 可用来存储具有关联关系的 key-value 键值对集合,存储元素中 key 是唯一的,每个 key 会对应一个 value 值。TreeMap 依据泛型定义,集合中的 key 值是有序的,TreeMap 的底层是一棵二叉树,可以通过树的二叉查找快速地找到键值对。key 的类型满足 ECMA 标准中要求的类型。TreeMap 中的键值是有序存储的。TreeMap 底层基于红黑树实现,可以进行快速地插入和删除。TreeMap 进行增、删、改、查操作的相关 API 如下:

1.2.4 TreeSet

TreeSet 可用来存储一系列值的集合,存储元素中 value 是唯一的。TreeSet 依据泛型定义,集合中的 value 值是有序的,TreeSet 的底层是一棵二叉树,可以通过树的二叉查找快速地找到该 value 值,value 的类型满足 ECMA 标准中要求的类型。TreeSet 中的值是有序存储的。TreeSet 底层基于红黑树实现,可以进行快速地插入和删除。TreeSet 进行增、删、改、查操作的相关 API 如下:

1.2.5 LightWeightMap

LigthWeightMap 可用来存储具有关联关系的 key-value 键值对集合,存储元素中 key 是唯一的,每个 key 会对应一个 value 值。LigthWeightMap 依据泛型定义,采用更加轻量级的结构,集合中的 key 值的查找依赖于 hash 值以及二分查找算法,通过一个数组存储 hash 值,然后映射到其他数组中的 key 值以及 value 值,key 的类型满足 ECMA 标准中要求的类型。

初始默认容量大小为 8,每次扩容大小为原始容量的 2 倍。LigthWeightMap 底层标识唯一 key 通过 hash 实现,其冲突策略为线性探测法,查找策略基于二分查找法。LigthWeightMap 进行增、删、改、查操作的相关 API 如下:

1.2.6 LightWeightSet

LigthWeightSet 可用来存储一系列值的集合,存储元素中 value 是唯一的。LigthWeightSet 依据泛型定义,采用更加轻量级的结构,初始默认容量大小为 8,每次扩容大小为原始容量的 2 倍。集合中的 value 值的查找依赖于 hash 以及二分查找算法,通过一个数组存储 hash 值,然后映射到其他数组中的 value 值,value 的类型满足 ECMA 标准中要求的类型。

LigthWeightSet 底层标识唯一 value 基于 hash 实现,其冲突策略为线性探测法,查找策略基于二分查找法。LigthWeightSet 进行增、删、改、查操作的相关 API 如下:

1.2.7 PlainArray

PlainArray 可用来存储具有关联关系的键值对集合,存储元素中 key 是唯一的,并且对于 PlainArray 来说,其 key 的类型为 number 类型。每个 key 会对应一个 value 值,类型依据泛型的定义,PlainArray 采用更加轻量级的结构,集合中的 key 值的查找依赖于二分查找算法,然后映射到其他数组中的 value 值。

初始默认容量大小为 16,每次扩容大小为原始容量的 2 倍。PlainArray 的查找策略基于二分查找法。PlainArray 进行增、删、改、查操作的相关 API 如下:

二、容器类的实现

下面我们将以 ArrayList 为例,为大家介绍,容器类的实现。包括容器类的初始化、容器类的接口调用、容器类对象模型的构建以及拦截器处理。

2.1 容器类初始化

在 ArkUI 开发框架中,通过 NAPI 的统一框架对外层提供容器类。下面,我们将以 ArrayList 为例,介绍基于 NAPI 的容器类的加载。如下图所示,是容器类初始化流程,在 NAPI 加载的过程中,会通过 ArkPrivate.Load 接口加载对应的容器类。ArrayList 在引擎中会初始化 Constructor 以及 Prototype 并返回,最后应用侧可以获得该容器类并使用。

2.2 容器类接口调用

在 ArkUI 开发框架中,容器类 API 的调用流程如下,用户先通过 new ArrayList 进入引擎得到对应的 arraylist 对象,然后可以通过 add 接口向对象中添加元素,元素最终会添加到一片和该 arraylist 绑定的内存空间。可以通过 [] 操作符进行元素获取,对于容器类而言,引擎会直接通过快速路径访问到元素存储位置,返回该值。

2.3 容器类对象模型

在 ArkUI 开发框架中,构造容器类对象模型的流程如下图所示,在运行时禁止再向对象上添加 Properties 属性,ArrayList 借用对象模型中的 elements 位置存储元素。

实现说明:通过 elements 存储数组元素,Length 为数组中元素个数,数组 Capatity 可以通过 elements 的长度获取。

扩容策略:ArrayList –> 1.5 倍

初始分配容量:ArrayList -> 10

(注:TS 中的实现,扩容策略及初始分配容量不感知)

2.4 拦截器处理

拦截器处理,是指通过禁止掉一些影响对象行为的操作,比如 delete、setPrototype 等,在运行时(Runtime)维护一个高效的容器类对象。以 ArrayList 为例,ArkCompiler 内部拦截的操作主要涉及 DeleteProperty、DefineProperty、GetProperty、SetPrototype、GetOwnPropertyKeys、HasProperty 等操作限制数组的 holy 添加,以及更改属性的 attributes 等操作,保证了不需要做 JSArray 必须做的 holy 判断、writable 判断等操作。

三、容器类API的使用

通过上文的介绍,相信大家对容器类已经有了比较深刻的认识。那么,我们怎么使用容器类 API 呢?本文列举常用的典型容器的使用示例,包括导入模块、增加元素、访问元素及修改等操作:

// ArrayList
import ArrayList from '@ohos.util.ArrayList' // 导入ArrayList模块
let arrayList = new ArrayList();
arrayList.add("a");
arrayList.add(1); // 增加元素
print(arrayList[0]); // 访问元素
arrayList[0] = one"; // 修改元素
print(arrayList[0]); // Vector
import Vector from '@ohos.util.Vector' // 导入Vector模块
let vector = new Vector();
vector.add("a");
let b = [1, 2, 3];
vector.add(b);
vector.add(false); // 增加元素
print(vector[0]); // 访问元素
print(vector.getFirstElement()); // 访问元素 // Deque
import Deque from '@ohos.util.Deque' // 导入Deque模块
let deque = new Deque;
deque.insertFront("a");
deque.insertFront(1); // 增加元素
print(deque[0]); // 访问元素
deque[0] = "one"; // 修改元素
print(deque[0]); // Stack
import Stack from '@ohos.util.Stack' // 导入Stack模块
let stack = new Stack();
stack.push("a");
stack.push(1); // 增加元素
print(stack[0]); // 访问元素
stack.pop(); // 弹出元素
print(stack.length); // List
import List from '@ohos.util.List' // 导入List模块
let list = new List;
list.add("a");
list.add(1);
let b = [1, 2, 3];
list.add(b); // 增加元素
print(list[0]); // 访问元素
print(list.get(0)); // 访问元素 // HashMap
import HashMap from '@ohos.util.HashMap' // 导入HashMap模块
let hashMap = new HashMap();
hashMap.set("a", 123);
hashMap.set(4, 123); // 增加元素
print(hashMap.hasKey(4)); // 判断是否含有某元素
print(hashMap.get("a")); // 访问元素 // TreeMap
import TreeMap from '@ohos.util.TreeMap' // 导入TreeMap模块
let treeMap = new TreeMap();
treeMap.set("a", 123);
treeMap.set("6", 356); // 增加元素
print(treeMap.get("a")); // 访问元素
print(treeMap.getFirstKey("a")); // 访问首元素
print(treeMap.getLastKey("a")); // 访问尾元素 // LightWeightMap
import LightWeightMap from '@ohos.util.LightWeightMap' // 导入LightWeightMap模块
let lightWeightMap = new LightWeightMap();
lightWeightMap.set("x", 123);
lightWeightMap.set("8", 356); // 增加元素
print(lightWeightMap.get("a")); // 访问元素
print(lightWeightMap.get("x")); // 访问元素
print(lightWeightMap.getIndexOfKey("8")); // 访问元素 // PlainArray
import PlainArray from '@ohos.util.PlainArray' // 导入PlainArray模块
let plainArray = new PlainArray();
plainArray.add(1, "sdd");
plainArray.add(2, "sff"); // 增加元素
print(plainArray.get(1)); // 访问元素
print(plainArray.getKeyAt(1)); // 访问元素

至此以上就是本期全部内容,期待广大开发者通过 ArkUI 开发框架的容器类开发出更多高性能的应用。

OpenHarmony 3.1 Beta版本关键特性解析——ArkUI容器类API介绍的更多相关文章

  1. OpenHarmony 3.1 Beta 版本关键特性解析——ArkUI canvas组件

    (以下内容来自开发者分享,不代表 OpenHarmony 项目群工作委员会观点) 江英杰 华为技术有限公司 canvas 是 ArkUI 开发框架里的画布组件,常用于自定义绘制图形.因为其轻量.灵活. ...

  2. OpenHarmony 3.1 Beta版本关键特性解析——HiStreamer框架大揭秘

    ​(以下内容来自开发者分享,不代表 OpenHarmony 项目群工作委员会观点)​ 陈国栋 数字多媒体技术在过去的数十年里得到了飞速的发展,多媒体终端设备如智能音箱.智能门锁.智能手表广泛应用于人们 ...

  3. OpenHarmony 3.1 Beta版本关键特性解析——HAP包安装实现剖析

    ​(以下内容来自开发者分享,不代表 OpenHarmony 项目群工作委员会观点)​ 石磊 随着社会的不断发展,人们逐渐注重更加高效.舒适.便捷.有趣的生活和工作体验. OpenAtom OpenHa ...

  4. OpenHarmony 3.1 Beta版本关键特性解析——探秘隐式查询

    ​(以下内容来自开发者分享,不代表 OpenHarmony 项目群工作委员会观点)​ 徐浩 隐式查询是 OpenAtom OpenHarmony(以下简称"OpenHarmony" ...

  5. OpenHarmony 3.1 Beta版本关键特性解析——OpenHarmony图形框架

    (以下内容来自开发者分享,不代表 OpenHarmony 项目群工作委员会观点) 李煜 华为技术有限公司 崔坤华为技术有限公司 众所周知,动画是系统和应用与用户交互的重要环节.动画效果的好坏会直接影响 ...

  6. OpenHarmony 3.1 Beta版本关键特性解析——分布式DeviceProfile

    (以下内容来自开发者分享,不代表 OpenHarmony 项目群工作委员会观点) 成翔 OpenAtom OpenHarmony(以下简称"OpenHarmony")作为分布式操作 ...

  7. OpenHarmony3.1 Release版本关键特性解析——Enhanced SWAP内存管理

    樊成阳 华为技术有限公司内核专家 陈杰 华为技术有限公司内核专家 OpenAtom OpenHarmony(以下简称"OpenHarmony")是面向全场景泛终端设备的操作系统,终 ...

  8. Unity 5.6 beta版本新特性

    http://manew.com/thread-98549-1-1.html 最新发布的beta版改进了编辑器和2D功能,图形性能更佳,加入新的视频播放器,并添加了对Facebook Gameroom ...

  9. OpenHarmony 3.1 Release版本发布

    OpenHarmony 3.1 Release 版本概述 当前版本在OpenHarmony 3.1 Beta的基础上,更新支持以下能力: 标准系统基础能力增强 本地基础音视频播放能力.视频硬编解码.相 ...

随机推荐

  1. bzoj4032/luoguP4112 [HEOI2015]最短不公共子串(后缀自动机+序列自动机上dp)

    bzoj4032/luoguP4112 [HEOI2015]最短不公共子串(后缀自动机+序列自动机上dp) bzoj Luogu 题解时间 给两个小写字母串 $ A $ , $ B $ ,请你计算: ...

  2. 《前端运维》三、Docker--2其他

    一.制作DockerFile docker的镜像类似于用一层一层的文件组成.inspect命令可以查看镜像或容器的的信息,其中Layers就是镜像的层文件,只读不能修改,基于镜像创建的容器会共享这些层 ...

  3. 摆烂期的Android学习笔记一

    Android大致分为四层架构1.Linux内核层:提供各种硬件驱动,如显示驱动,音频驱动,相机驱 动,蓝牙驱动.... 2.系统运行库层:通过C/c++库为android地图提供支持 3.应用框架层 ...

  4. 半吊子菜鸟学Web开发 -- PHP学习 1-基础语法

    1索引数组 $fruit = array("苹果","香蕉","菠萝"): print_r($fruit); 索引数组的初始化,有三种方式: ...

  5. macOS逆向-如何分析macOS软件

    目录 macOS逆向-如何分析macOS软件 0x00 前言: 0x01 分析环境搭建: 安装Clang 安装Radare2 关于HT Editor 什么是Radare2 Radare2的手动安装 测 ...

  6. Maven项目报错:“No goals have been specified for this build”解决办法

    clean install scf:run第一种解决办法:找到pom.xml文件,在<build>标签里面添加如下所示的代码即可.<defaultGoal> compile & ...

  7. IDEA端口占用的解决方案

    使用端口查找到对应的进程PID: netstat -ano | findstr "端口" 查找到对应PID的进程信息 tasklist /v /fi "PID eq &l ...

  8. SpringBoot bean映射yml中的属性举例

    pom:导入配置文件处理器,配置文件进行绑定就会有提示 <dependency> <groupId>org.springframework.boot</groupId&g ...

  9. 上传文件到阿里云linux服务器(windows到Linux的文件上传)

    在"运行"中输入cmd,打开控制台,切换到刚才Putty的安装目录下,我的是E:\Putty,然后输入pscp命令,我们需要这个命令来实现文件的上传.如下命令格式: F:\PuTT ...

  10. Django的models中filter的各种用法及官方手册的网址

    __exact 精确等于 like 'aaa' __iexact 精确等于 忽略大小写 ilike 'aaa' __contains 包含 like '%aaa%' __icontains 包含 忽略 ...