OpenHarmony 实战开发——ArkUI容器类API介绍

容器类,顾名思义就是存储的类,用于存储各种数据类型的元素,并具备一系列处理数据元素的方法。在 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 开发的内容,下面特别准备了一些相关的参考学习资料:

OpenHarmony 开发环境搭建:https://qr18.cn/CgxrRy

《OpenHarmony源码解析》:https://qr18.cn/CgxrRy

  • 搭建开发环境
  • Windows 开发环境的搭建
  • Ubuntu 开发环境搭建
  • Linux 与 Windows 之间的文件共享
  • ……

系统架构分析:https://qr18.cn/CgxrRy

  • 构建子系统
  • 启动流程
  • 子系统
  • 分布式任务调度子系统
  • 分布式通信子系统
  • 驱动子系统
  • ……

OpenHarmony 设备开发学习手册:https://qr18.cn/CgxrRy

在这里插入图片描述

OpenHarmony面试题(内含参考答案):https://qr18.cn/CgxrRy

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/12863.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++map容器关联式容器

Cmap 1. 关联式容器 vector、list、deque、forward_list(C11)等STL容器,其底层为线性序列的数据结构,里面存储的是元素本身,这样的容器被统称为序列式容器。而map、set是一种关联式容器,关联式容器也是用来存储数据的&#xff0…

【开发】模型部署笔记

目录 模型量化 模型量化 1、模型量化优点 低精度模型表示模型权重数值格式为FP16(半精度浮点)或者INT8(8位定点整数),但是目前低精度往往就指代INT8。常规精度模型则一般表示模型权重数值格式为FP32(32位…

策略模式详解

策略模式 1 概述 先看下面的图片,我们去旅游选择出行模式有很多种,可以骑自行车、可以坐汽车、可以坐火车、可以坐飞机。 作为一个程序猿,开发需要选择一款开发工具,当然可以进行代码开发的工具有很多,可以选择Idea进…

gitlab webhook触发jenkins任务

配置jenkins 安装gitlab插件 配置jenkins job 选择gitlab webhook触发 在高级中生成token 代码仓设置 新增webhook 配置webhook 测试连接 缺点,不能带gitLab事件的参数!!!

Spark RDD案例:统计网站每月访问量

这个项目利用Spark技术,通过统计网站访问记录中的日期信息,实现了对每月访问量的统计和排序。通过分析数据,我们可以了解到不同月份的网站访问情况,为进一步优化网站内容和推广策略提供数据支持。 使用Spark统计网站每月访问量 …

Apache2.4和PHP8的量子纠缠

Apache不建议你用,PHP建议使用

一种基于电场连续性的高压MOSFET紧凑模型,用于精确表征电容特性

来源:A Compact Model of High-Voltage MOSFET Based on Electric Field Continuity for Accurate Characterization of Capacitance(TED 24年) 摘要 本文提出了一种新的高压MOSFET(HV MOS)紧凑模型,以消…

【hana】hana1.0多容器常用命令

基础命令 数据库 连接数据库 hdbsql -u system -p {passwd} -i 02 -d {dbname}查询所有数据库 SELECT DATABASE_NAME, ACTIVE_STATUS FROM M_DATABASES;停止数据库,会修改数据库状态为No ALTER SYSTEM STOP DATABASE testdb; 启动数据库,会修改数据…

多线程的代码案例

目录 单例模式 饿汉模式 懒汉模式 阻塞队列 生产者消费者模型意义: 阻塞队列使用方法 实现阻塞队列 阻塞队列实现生产者消费者模型 定时器 实现简单的定时器 工厂模式 线程池 为啥呢? 从池子里面取 比 创建线程 效率更高 线程池的创建 怎么填坑 ThreadPoolExec…

图解堆排序【一眼看穿逻辑思路】

P. S.:以下代码均在VS2019环境下测试,不代表所有编译器均可通过。 P. S.:测试代码均未展示头文件stdio.h的声明,使用时请自行添加。 目录 1、堆的概念2、实现堆排序前的准备工作3、堆排序的思路3.1 第一步3.2 第二步 4、结语 1、…

音视频捕捉技术:LCC382 SDI采集卡深度解析

在日新月异的多媒体时代,高质量的音视频采集已成为众多领域不可或缺的一环。为此,灵卡科技精心打造了LCC382 —— 一款集高效性、灵活性与前沿技术于一身的SDI输入与环出、HDMI输出音视频采集卡,旨在满足从专业直播、视频会议到医疗影像、安防…

网页版Figma汉化

最近学习Figma,简单介绍一下网页版Figma的汉化方法 1.打开网址:Figma软件汉化-Figma中文版下载-Figma中文社区 2.下载汉化插件离线包 解压汉化包 3.点开谷歌的管理扩展程序 4.点击加载已解压的扩展程序,选择刚刚解压的包 这样就安装好了汉化…

QT状态机2-含终止状态的嵌套状态机

#include "MainWindow.h" #include "ui_MainWindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)

前馈神经网络FNN、多层感知机MLP和反向传播推导

目录 一、前馈神经网络FNN 激活函数的使用 二、多层感知机MLP MLP的典型结构 多层感知机MLP的特点 和前馈神经网络FNN的区别 三、传播推导 1、前向传播(Forward propagation) (1)输入层到隐藏层 (2)隐藏层到输出层 2、…

Java面试八股之WeakHashMap的工作原理

简述WeakHashMap的工作原理 弱键(Weak Keys): WeakHashMap 的键(keys)是通过 WeakReference 弱引用进行封装的。弱引用是一种特殊的引用类型,它不会阻止所引用的对象被垃圾收集器回收。这意味着&#xff…

冥想训练具体方法有哪些|流静冥想

冥想是一种身体的放松和敏锐的警觉性相结合的状态。 每日练习的好处远不止你花在集中注意力的那几分钟。桑托雷利是建在乌斯特的马萨诸塞大学医学院的减压诊所的所长,她也是《自愈》的作者,她说:"冥想是一种工具,通过练习&a…

云手机的优缺点分析

云手机,作为云计算领域的创新,致力于提供更为灵活的移动设备体验,特别适用于那些希望在不同设备之间无缝切换的用户。虽然云手机带来了一系列优势,但也伴随着一些挑战,比如网络延迟可能会影响用户体验,特别…

网络安全|隐藏IP地址的5种不同方法

隐藏计算机的IP地址在互联网在线活动种可以保护个人隐私,这是在线活动的一种常见做法,包括隐私问题、安全性和访问限制内容等场景。那么如何做到呢?有很5种方法分享。每种方法都有自己的优点和缺点。 1. 虚拟网络 当您连接到虚拟服务器时,您…

Dubbo配置上的一些概念

对于dubbo在spring中我们可能看到有如下配置(可参考Schema 配置参考手册 | Apache Dubbo): dubbo:application:id: dubbo-account-examplename: dubbo-account-example# 是否启用 Dubbo 的 QoS(Quality of Service)服…