您的位置  > 互联网

方舟开发框架中API的使用方法以及相关API使用说明

1.容器API介绍

方舟开发框架中提供了线性和非线性两种容器类,总共14种。 每个容器都有自己的特点和使用场景。 下面,我们就一一为大家讲述。

1 线性容器类

线性容器类底层主要通过数组来实现,包括List、Deque、Queue和Stack七种类型。 线性容器API充分考虑了数据访问的速度。 增、删、改、查询等操作可以在运行时()期间通过字节码指令完成。

1.

也就是说,动态数组可以用来构造全局数组对象。 根据通用定义,存储位置要求是初始容量为10的连续内存空间,并且支持动态扩展。 每次扩容是原来容量的1.5倍。 增、删、改、查操作相关API如下:

2.

它是指可以用来构造全局数组对象的连续存储结构。 根据通用定义,存储位置要求是一个连续的内存空间,初始容量为10,并且支持动态扩展,每次扩展是原来容量的2倍。

由于扩展速度较高,适合频繁添加数据的场景。 在支持算子访问的基础上,还增加了get/set接口,提供更完善的验证和容错机制,满足用户不同场景的需求。 增、删、改、查操作相关API如下:

3.列表

List可以用来构造单向链表对象,即只能从头节点到尾节点进行访问。 根据泛型定义,List在内存中的存储位置可以是不连续的。

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

4.

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

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

5.队列

Queue可以用来构造队列对象,存储元素遵循先进先出的规则。 队列基于通用定义,要求存储位置为连续的内存空间,初始容量为8,并支持动态扩展。 每次扩容的容量是原来容量的两倍。 Queue底层使用循环队列实现,入队和出队操作效率比较高。 Queue执行增删改查操作的相关API如下:

6. 双端队列

Deque 可用于构造双端队列对象。 存储元素遵循先进先出规则。 双端队列可以从对端或队列尾部访问。 根据通用定义,Deque要求存储位置为连续的内存空间,初始容量为8,并支持动态扩展。 每次扩容都是原来容量的两倍。 Deque底层使用循环队列实现,入队和出队操作效率比较高。 Deque执行增删改查操作的相关API如下:

7. 堆栈

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

2 非线性容器类

非线性容器类底层通过哈希或者红黑树实现,包括七种类型。 非线性容器类中的键和值类型均符合ECMA标准。

1.

它可用于存储关联键值对的集合。 存储元素中的键是唯一的,每个键对应一个值。 根据通用定义,键的存储位置由其在集合中的哈希值决定,从而快速找到键值对。 初始容量16个,支持动态扩展。 每次扩容都是原来容量的两倍。 底层基于实现,冲突策略采用链地址方式。 增、删、改、查操作相关API如下:

2.

它可以用来存储值的集合,并且存储的元素中的值是唯一的。 根据通用定义。 值在集合中的存储位置由其哈希值决定,从而可以快速找到该值。 初始容量16个,支持动态扩展。 每次扩容都是原来容量的两倍。 值的类型满足ECMA标准的要求。 底层基于实现,冲突策略采用链地址方式。 增、删、改、查操作相关API如下:

3.

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

4.

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

5.

它可用于存储关联键值对的集合。 存储元素中的键是唯一的,每个键对应一个值。 根据通用定义,采用更轻量级的结构。 集合中键值的查找依赖于哈希值和二分查找算法。 哈希值存储在一个数组中,然后映射到其他数组中的键值和值值。 密钥 类型满足 ECMA 标准的要求。

初始默认容量为8,每次扩容为原来容量的2倍。 底层标识符的唯一键通过哈希实现,其冲突策略是线性检测方法,搜索策略是基于二分查找方法。 增、删、改、查操作相关API如下:

6.

它可以用来存储值的集合,并且存储的元素中的值是唯一的。 在通用定义的基础上,采用了更轻量级的结构。 初始默认容量为8,每次扩容为原来容量的2倍。 集合中value值的搜索依赖于哈希和二分搜索算法。 哈希值存储在一个数组中,然后映射到其他数组中的value值。 值的类型满足ECMA标准的要求。

底层标识符的唯一值是基于哈希实现的,其冲突策略是线性检测方法,搜索策略是基于二分查找方法。 增、删、改、查操作相关API如下:

7.

它可用于存储具有关联关系的键值对的集合。 存储的元素中的键是唯一的,对于 ,其键的类型是 type。 每个键对应一个值。 类型基于泛型的定义,采用更轻量级的结构。 对集合中键值的搜索依赖于二分查找算法,然后映射到其他数组中的值。

初始默认容量为16,每次扩容为原来容量的2倍。 搜索策略基于二分搜索方法。 增、删、改、查操作相关API如下:

2.容器类的实现

下面我们就以一个例子来给大家介绍一下容器类的实现。 包括容器类的初始化、容器类的接口调用、容器类对象模型的构建和拦截器处理。

1 容器类初始化

在方舟开发框架中,通过NAPI的统一框架向外层提供容器类。 下面,我们以一个例子来介绍基于NAPI的容器类的加载。 如下图所示,就是容器类的初始化过程。 NAPI加载过程中,会通过.Load接口加载对应的容器类。 它会在引擎中初始化并返回,最终应用程序端可以获得容器类并使用它。

图1 类初始化流程

2 容器类接口调用

在方舟开发框架中,容器类API的调用流程如图2所示。用户首先通过new进入引擎获取对应的对象,然后可以通过add接口向对象添加元素。 这些元素最终将被添加到一块和装订中。 内存空间。 可以通过[]运算符获取元素。 对于容器类,引擎会通过快速路径直接访问元素存储位置并返回值。

图2 容器API调用流程

类对象模型

在方舟开发框架中,构建容器类对象模型的流程如下图所示。 禁止在运行时向对象添加属性以及借用对象模型中的位置存储元素。

图3 容器类对象模型构建流程

实现说明:通过存储数组元素,就是数组的元素个数,可以得到数组的长度。

扩容策略:–>1.5倍

初始分配容量:-> 10

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

4 拦截器处理

拦截器处理是指在运行时维护一个高效的容器类对象(),通过禁止一些影响对象行为的操作,例如等等。如图4所示,内部拦截操作主要涉及以下操作, 、、、、、、等操作限制圣向数组的添加,以及改变属性等操作,保证不需要进行必要的圣判断、判定等操作。

图4 拦截器处理

3.容器API的使用

通过上面的介绍,相信大家对容器类有了比较深入的了解。 那么,我们如何使用容器API呢? 本文列出了常用的典型容器的示例,包括导入模块、添加元素、访问元素、修改元素等操作:

// ArrayListimport 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]);
// Vectorimport 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()); // 访问元素
// Dequeimport 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]);
// Stackimport Stack from '@ohos.util.Stack'  // 导入Stack模块  let stack = new Stack();stack.push("a");stack.push(1);   // 增加元素print(stack[0]); // 访问元素stack.pop();     // 弹出元素print(stack.length);
// Listimport 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)); // 访问元素
// HashMapimport 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"));  // 访问元素
// TreeMapimport 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"));  // 访问尾元素
// LightWeightMapimport 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")); // 访问元素
// PlainArrayimport 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)); // 访问元素