容器類,顧名思義就是存儲(chǔ)的類,用于存儲(chǔ)各種數(shù)據(jù)類型的元素,并具備一系列處理數(shù)據(jù)元素的方法。在 ArkUI 開發(fā)框架中,容器類采用了類似靜態(tài)的語言來實(shí)現(xiàn),并通過 NAPI 框架對(duì)外提供。通過對(duì)存儲(chǔ)位置以及屬性的限制,讓每種類型的數(shù)據(jù)都能在完成自身功能的基礎(chǔ)上剪除冗余分支,保證了數(shù)據(jù)的高效訪問,提升了應(yīng)用的性能。本期,我們將為大家介紹 ArkUI 開發(fā)框架中容器類的各種類型以及相關(guān) API 的使用。
容器類API介紹
在 ArkUI 開發(fā)框架中,提供了線性和非線性兩類容器類,共 14 種,每種容器都有自身的特性及使用場景。下面,我們將為大家一一道來。1.1線性容器類
線性容器類底層主要通過數(shù)組實(shí)現(xiàn),包括 ArrayList、Vector、List、LinkedList、Deque、Queue、Stack 七種。線性容器類 API,充分考慮了數(shù)據(jù)訪問的速度,實(shí)現(xiàn)了運(yùn)行時(shí)(Runtime)通過一條指令就可以完成增刪改查等操作。
1.1.1 ArrayList
ArrayList 即動(dòng)態(tài)數(shù)組,可用來構(gòu)造全局的數(shù)組對(duì)象。ArrayList 依據(jù)泛型定義,要求存儲(chǔ)位置是一片連續(xù)的內(nèi)存空間,初始容量大小為 10,并支持動(dòng)態(tài)擴(kuò)容,每次擴(kuò)容大小為原始容量的 1.5 倍。ArrayList 進(jìn)行增、刪、改、查操作的相關(guān) API 如下:
1.1.2 Vector
Vector 是指連續(xù)存儲(chǔ)結(jié)構(gòu),可用來構(gòu)造全局的數(shù)組對(duì)象。Vector 依據(jù)泛型定義,要求存儲(chǔ)位置是一片連續(xù)的內(nèi)存空間,初始容量大小為 10,并支持動(dòng)態(tài)擴(kuò)容,每次擴(kuò)容大小為原始容量的2倍。
由于 Vector 擴(kuò)容速度高于 ArrayList,所以適用于數(shù)據(jù)添加比較頻繁的場景。Vector 在支持操作符訪問的基礎(chǔ)上,還增加了 get/set 接口,提供更為完善的校驗(yàn)及容錯(cuò)機(jī)制,滿足用戶不同場景下的需求。Vector 進(jìn)行增、刪、改、查操作的相關(guān) API 如下:
1.1.3 List
List 可用來構(gòu)造一個(gè)單向鏈表對(duì)象,即只能通過頭結(jié)點(diǎn)開始訪問到尾節(jié)點(diǎn)。List 依據(jù)泛型定義,在內(nèi)存中的存儲(chǔ)位置可以是不連續(xù)的。
可以通過 get/set 等接口對(duì)存儲(chǔ)的元素進(jìn)行修改,List 進(jìn)行增、刪、改、查操作的相關(guān) API 如下:
1.1.4 LinkedList
LinkedList 可用來構(gòu)造一個(gè)雙向鏈表對(duì)象,可以在某一節(jié)點(diǎn)向前或者向后遍歷 List。LinkedList 依據(jù)泛型定義,在內(nèi)存中的存儲(chǔ)位置可以是不連續(xù)的。
可以通過 get/set 等接口對(duì)存儲(chǔ)的元素進(jìn)行修改,LinkedList 進(jìn)行增、刪、改、查操作的相關(guān) API 如下:
1.1.5 Queue
Queue 可用來構(gòu)造隊(duì)列對(duì)象,存儲(chǔ)元素遵循先進(jìn)先出的規(guī)則。Queue 依據(jù)泛型定義,要求存儲(chǔ)位置是一片連續(xù)的內(nèi)存空間,初始容量大小為 8,并支持動(dòng)態(tài)擴(kuò)容,每次擴(kuò)容大小為原始容量的 2 倍。Queue 底層采用循環(huán)隊(duì)列實(shí)現(xiàn),入隊(duì)及出隊(duì)操作效率都比較高。Queue 進(jìn)行增、刪、改、查操作的相關(guān) API 如下:
1.1.6 Deque
Deque 可用來構(gòu)造雙端隊(duì)列對(duì)象,存儲(chǔ)元素遵循先進(jìn)先出的規(guī)則,雙端隊(duì)列可以分別從對(duì)頭或者隊(duì)尾進(jìn)行訪問。Deque 依據(jù)泛型定義,要求存儲(chǔ)位置是一片連續(xù)的內(nèi)存空間,其初始容量大小為 8,并支持動(dòng)態(tài)擴(kuò)容,每次擴(kuò)容大小為原始容量的 2 倍。Deque 底層采用循環(huán)隊(duì)列實(shí)現(xiàn),入隊(duì)及出隊(duì)操作效率都比較高。Deque 進(jìn)行增、刪、改、查操作的相關(guān) API 如下:
1.1.7 Stack
Stack 可用來構(gòu)造棧對(duì)象,存儲(chǔ)元素遵循后進(jìn)先出的規(guī)則。Stack 依據(jù)泛型定義,要求存儲(chǔ)位置是一片連續(xù)的內(nèi)存空間,初始容量大小為 8,并支持動(dòng)態(tài)擴(kuò)容,每次擴(kuò)容大小為原始容量的 1.5 倍。Stack 底層基于數(shù)組實(shí)現(xiàn),入棧出棧均從數(shù)組的一端操作,Stack 進(jìn)行增、刪、改、查操作的相關(guān) API 如下:
1.2非線性容器類
非線性容器類底層通過 hash 或者紅黑樹實(shí)現(xiàn),包括 HashMap、HashSet、TreeMap、TreeSet、LightWeightMap、LightWeightSet、PlainArray 七種。非線性容器類中的 key 及 value 的類型均滿足 ECMA 標(biāo)準(zhǔn)。
1.2.1 HashMap
HashMap 可用來存儲(chǔ)具有關(guān)聯(lián)關(guān)系的 key-value 鍵值對(duì)集合,存儲(chǔ)元素中 key 是唯一的,每個(gè) key 會(huì)對(duì)應(yīng)一個(gè) value 值。HashMap 依據(jù)泛型定義,集合中通過 key 的 hash 值確定其存儲(chǔ)位置,從而快速找到鍵值對(duì)。HashMap 的初始容量大小為 16,并支持動(dòng)態(tài)擴(kuò)容,每次擴(kuò)容大小為原始容量的 2 倍。HashMap 底層基于 HashTable 實(shí)現(xiàn),沖突策略采用鏈地址法。HashMap 進(jìn)行增、刪、改、查操作的相關(guān) API 如下:
1.2.2 HashSet
HashSet 可用來存儲(chǔ)一系列值的集合,存儲(chǔ)元素中 value 是唯一的。依據(jù)泛型定義。集合中通過 value 的 hash 值確定其存儲(chǔ)位置,從而快速找到該值。HashSet 初始容量大小為 16,支持動(dòng)態(tài)擴(kuò)容,每次擴(kuò)容大小為原始容量的 2 倍。value 的類型滿足 ECMA 標(biāo)準(zhǔn)中要求的類型。HashSet 底層基于 HashTable 實(shí)現(xiàn),沖突策略采用鏈地址法。HashSet 進(jìn)行增、刪、改、查操作的相關(guān) API 如下:
1.2.3 TreeMap
TreeMap 可用來存儲(chǔ)具有關(guān)聯(lián)關(guān)系的 key-value 鍵值對(duì)集合,存儲(chǔ)元素中 key 是唯一的,每個(gè) key 會(huì)對(duì)應(yīng)一個(gè) value 值。TreeMap 依據(jù)泛型定義,集合中的 key 值是有序的,TreeMap 的底層是一棵二叉樹,可以通過樹的二叉查找快速地找到鍵值對(duì)。key 的類型滿足 ECMA 標(biāo)準(zhǔn)中要求的類型。TreeMap 中的鍵值是有序存儲(chǔ)的。TreeMap 底層基于紅黑樹實(shí)現(xiàn),可以進(jìn)行快速地插入和刪除。TreeMap 進(jìn)行增、刪、改、查操作的相關(guān) API 如下:
1.2.4 TreeSet
TreeSet 可用來存儲(chǔ)一系列值的集合,存儲(chǔ)元素中 value 是唯一的。TreeSet 依據(jù)泛型定義,集合中的 value 值是有序的,TreeSet 的底層是一棵二叉樹,可以通過樹的二叉查找快速地找到該 value 值,value 的類型滿足 ECMA 標(biāo)準(zhǔn)中要求的類型。TreeSet 中的值是有序存儲(chǔ)的。TreeSet 底層基于紅黑樹實(shí)現(xiàn),可以進(jìn)行快速地插入和刪除。TreeSet 進(jìn)行增、刪、改、查操作的相關(guān) API 如下:
1.2.5 LightWeightMap
LigthWeightMap 可用來存儲(chǔ)具有關(guān)聯(lián)關(guān)系的 key-value 鍵值對(duì)集合,存儲(chǔ)元素中 key 是唯一的,每個(gè) key 會(huì)對(duì)應(yīng)一個(gè) value 值。LigthWeightMap 依據(jù)泛型定義,采用更加輕量級(jí)的結(jié)構(gòu),集合中的 key 值的查找依賴于 hash 值以及二分查找算法,通過一個(gè)數(shù)組存儲(chǔ) hash 值,然后映射到其他數(shù)組中的 key 值以及 value 值,key 的類型滿足 ECMA 標(biāo)準(zhǔn)中要求的類型。
初始默認(rèn)容量大小為 8,每次擴(kuò)容大小為原始容量的 2 倍。LigthWeightMap 底層標(biāo)識(shí)唯一 key 通過 hash 實(shí)現(xiàn),其沖突策略為線性探測(cè)法,查找策略基于二分查找法。LigthWeightMap 進(jìn)行增、刪、改、查操作的相關(guān) API 如下:
1.2.6 LightWeightSet
LigthWeightSet 可用來存儲(chǔ)一系列值的集合,存儲(chǔ)元素中 value 是唯一的。LigthWeightSet 依據(jù)泛型定義,采用更加輕量級(jí)的結(jié)構(gòu),初始默認(rèn)容量大小為 8,每次擴(kuò)容大小為原始容量的 2 倍。集合中的 value 值的查找依賴于 hash 以及二分查找算法,通過一個(gè)數(shù)組存儲(chǔ) hash 值,然后映射到其他數(shù)組中的 value 值,value 的類型滿足 ECMA 標(biāo)準(zhǔn)中要求的類型。
LigthWeightSet 底層標(biāo)識(shí)唯一 value 基于 hash 實(shí)現(xiàn),其沖突策略為線性探測(cè)法,查找策略基于二分查找法。LigthWeightSet 進(jìn)行增、刪、改、查操作的相關(guān) API 如下:
1.2.7 PlainArray
PlainArray 可用來存儲(chǔ)具有關(guān)聯(lián)關(guān)系的鍵值對(duì)集合,存儲(chǔ)元素中 key 是唯一的,并且對(duì)于 PlainArray 來說,其 key 的類型為 number 類型。每個(gè) key 會(huì)對(duì)應(yīng)一個(gè) value 值,類型依據(jù)泛型的定義,PlainArray 采用更加輕量級(jí)的結(jié)構(gòu),集合中的 key 值的查找依賴于二分查找算法,然后映射到其他數(shù)組中的 value 值。
初始默認(rèn)容量大小為 16,每次擴(kuò)容大小為原始容量的 2 倍。PlainArray 的查找策略基于二分查找法。PlainArray 進(jìn)行增、刪、改、查操作的相關(guān) API 如下:
容器類的實(shí)現(xiàn)
下面我們將以 ArrayList 為例,為大家介紹,容器類的實(shí)現(xiàn)。包括容器類的初始化、容器類的接口調(diào)用、容器類對(duì)象模型的構(gòu)建以及攔截器處理。
2.1 容器類初始化
在 ArkUI 開發(fā)框架中,通過 NAPI 的統(tǒng)一框架對(duì)外層提供容器類。下面,我們將以 ArrayList 為例,介紹基于 NAPI 的容器類的加載。如下圖所示,是容器類初始化流程,在 NAPI 加載的過程中,會(huì)通過 ArkPrivate.Load 接口加載對(duì)應(yīng)的容器類。ArrayList 在引擎中會(huì)初始化 Constructor 以及 Prototype 并返回,最后應(yīng)用側(cè)可以獲得該容器類并使用。
2.2 容器類接口調(diào)用
在 ArkUI 開發(fā)框架中,容器類 API 的調(diào)用流程如下,用戶先通過 new ArrayList 進(jìn)入引擎得到對(duì)應(yīng)的 arraylist 對(duì)象,然后可以通過 add 接口向?qū)ο笾刑砑釉?,元素最終會(huì)添加到一片和該 arraylist 綁定的內(nèi)存空間。可以通過 [] 操作符進(jìn)行元素獲取,對(duì)于容器類而言,引擎會(huì)直接通過快速路徑訪問到元素存儲(chǔ)位置,返回該值。
2.3 容器類對(duì)象模型
在 ArkUI 開發(fā)框架中,構(gòu)造容器類對(duì)象模型的流程如下圖所示,在運(yùn)行時(shí)禁止再向?qū)ο笊咸砑?Properties 屬性,ArrayList 借用對(duì)象模型中的 elements 位置存儲(chǔ)元素。
實(shí)現(xiàn)說明:通過 elements 存儲(chǔ)數(shù)組元素,Length 為數(shù)組中元素個(gè)數(shù),數(shù)組 Capatity 可以通過 elements 的長度獲取。
擴(kuò)容策略:ArrayList –> 1.5 倍
初始分配容量:ArrayList -> 10
(注:TS 中的實(shí)現(xiàn),擴(kuò)容策略及初始分配容量不感知)
2.4 攔截器處理
攔截器處理,是指通過禁止掉一些影響對(duì)象行為的操作,比如 delete、setPrototype 等,在運(yùn)行時(shí)(Runtime)維護(hù)一個(gè)高效的容器類對(duì)象。以 ArrayList 為例,ArkCompiler 內(nèi)部攔截的操作主要涉及 DeleteProperty、DefineProperty、GetProperty、SetPrototype、GetOwnPropertyKeys、HasProperty 等操作限制數(shù)組的 holy 添加,以及更改屬性的 attributes 等操作,保證了不需要做 JSArray 必須做的 holy 判斷、writable 判斷等操作。
容器類API的使用
通過上文的介紹,相信大家對(duì)容器類已經(jīng)有了比較深刻的認(rèn)識(shí)。那么,我們?cè)趺词褂萌萜黝?API 呢?本文列舉常用的典型容器的使用示例,包括導(dǎo)入模塊、增加元素、訪問元素及修改等操作:
// ArrayList
import ArrayList from '@ohos.util.ArrayList' // 導(dǎo)入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' // 導(dǎo)入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' // 導(dǎo)入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' // 導(dǎo)入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' // 導(dǎo)入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' // 導(dǎo)入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' // 導(dǎo)入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' // 導(dǎo)入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' // 導(dǎo)入PlainArray模塊
let plainArray = new PlainArray();
plainArray.add(1, "sdd");
plainArray.add(2, "sff"); // 增加元素
print(plainArray.get(1)); // 訪問元素
print(plainArray.getKeyAt(1));//訪問元素
至此以上就是本期全部內(nèi)容,期待廣大開發(fā)者通過 ArkUI 開發(fā)框架的容器類開發(fā)出更多高性能的應(yīng)用。
審核編輯 :李倩
-
API
+關(guān)注
關(guān)注
2文章
1499瀏覽量
61960 -
容器
+關(guān)注
關(guān)注
0文章
495瀏覽量
22060 -
OpenHarmony
+關(guān)注
關(guān)注
25文章
3713瀏覽量
16254
原文標(biāo)題:OpenHarmony 3.1 Beta版本關(guān)鍵特性解析——ArkUI開發(fā)框架容器類API的介紹與使用
文章出處:【微信號(hào):gh_e4f28cfa3159,微信公眾號(hào):OpenAtom OpenHarmony】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論