一、容器類API介紹
在方舟開發(fā)框架中,提供了線性和非線性兩類容器類,共14種,每種容器都有自身的特性及使用場景。下面,我們將為大家一一道來。
鴻蒙開發(fā)指導文檔:[gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md
]
線性容器類
線性容器類底層主要通過數(shù)組實現(xiàn),包括ArrayList、Vector、List、LinkedList、Deque、Queue、Stack七種。線性容器類API,充分考慮了數(shù)據(jù)訪問的速度,運行時(Runtime)通過一條字節(jié)碼指令就可以完成增刪改查等操作。
1. ArrayList
ArrayList即動態(tài)數(shù)組,可用來構造全局的數(shù)組對象。ArrayList依據(jù)泛型定義,要求存儲位置是一片連續(xù)的內存空間,初始容量大小為10,并支持動態(tài)擴容,每次擴容大小為原始容量的1.5倍。ArrayList進行增、刪、改、查操作的相關API如下:
2. Vector
Vector 是指連續(xù)存儲結構,可用來構造全局的數(shù)組對象。Vector依據(jù)泛型定義,要求存儲位置是一片連續(xù)的內存空間,初始容量大小為10,并支持動態(tài)擴容,每次擴容大小為原始容量的2倍。
由于Vector擴容速度高于ArrayList,所以適用于數(shù)據(jù)添加比較頻繁的場景。Vector在支持操作符訪問的基礎上,還增加了get/set接口,提供更為完善的校驗及容錯機制,滿足用戶不同場景下的需求。Vector進行增、刪、改、查操作的相關API如下:
3. List
List可用來構造一個單向鏈表對象,即只能通過頭結點開始訪問到尾節(jié)點。List依據(jù)泛型定義,在內存中的存儲位置可以是不連續(xù)的。
可以通過get/set等接口對存儲的元素進行修改,List進行增、刪、改、查操作的相關API如下:
4. LinkedList
LinkedList可用來構造一個雙向鏈表對象,可以在某一節(jié)點向前或者向后遍歷List。LinkedList依據(jù)泛型定義,在內存中的存儲位置可以是不連續(xù)的。
可以通過get/set等接口對存儲的元素進行修改,LinkedList進行增、刪、改、查操作的相關API如下:
5. Queue
Queue可用來構造隊列對象,存儲元素遵循先進先出的規(guī)則。Queue依據(jù)泛型定義,要求存儲位置是一片連續(xù)的內存空間,初始容量大小為8,并支持動態(tài)擴容,每次擴容大小為原始容量的2倍。Queue底層采用循環(huán)隊列實現(xiàn),入隊及出隊操作效率都比較高。Queue進行增、刪、改、查操作的相關API如下:
6. Deque
Deque可用來構造雙端隊列對象,存儲元素遵循先進先出的規(guī)則,雙端隊列可以分別從對頭或者隊尾進行訪問。Deque依據(jù)泛型定義,要求存儲位置是一片連續(xù)的內存空間,其初始容量大小為8,并支持動態(tài)擴容,每次擴容大小為原始容量的2倍。Deque底層采用循環(huán)隊列實現(xiàn),入隊及出隊操作效率都比較高。Deque進行增、刪、改、查操作的相關API如下:
7. Stack
Stack可用來構造棧對象,存儲元素遵循后進先出的規(guī)則。Stack依據(jù)泛型定義,要求存儲位置是一片連續(xù)的內存空間,初始容量大小為8,并支持動態(tài)擴容,每次擴容大小為原始容量的1.5倍。Stack底層基于數(shù)組實現(xiàn),入棧出棧均從數(shù)組的一端操作,Stack進行增、刪、改、查操作的相關API如下:
非線性容器類
非線性容器類底層通過hash或者紅黑樹實現(xiàn),包括HashMap、HashSet、TreeMap、TreeSet、LightWeightMap、LightWeightSet、PlainArray七種。非線性容器類中的key及value的類型均滿足ECMA標準。
1. HashMap
HashMap可用來存儲具有關聯(lián)關系的key-value鍵值對集合,存儲元素中key是唯一的,每個key會對應一個value值。HashMap依據(jù)泛型定義,集合中通過key的hash值確定其存儲位置,從而快速找到鍵值對。HashMap的初始容量大小為16,并支持動態(tài)擴容,每次擴容大小為原始容量的2倍。HashMap底層基于HashTable實現(xiàn),沖突策略采用鏈地址法。HashMap進行增、刪、改、查操作的相關API如下:
2. HashSet
HashSet可用來存儲一系列值的集合,存儲元素中value是唯一的。依據(jù)泛型定義。集合中通過value的hash值確定其存儲位置,從而快速找到該值。HashSet初始容量大小為16,支持動態(tài)擴容,每次擴容大小為原始容量的2倍。value的類型滿足ECMA標準中要求的類型。HashSet底層基于HashTable實現(xiàn),沖突策略采用鏈地址法。HashSet進行增、刪、改、查操作的相關API如下:
3. TreeMap
TreeMap可用來存儲具有關聯(lián)關系的key-value鍵值對集合,存儲元素中key是唯一的,每個key會對應一個value值。TreeMap依據(jù)泛型定義,集合中的key值是有序的,TreeMap的底層是一棵二叉樹,可以通過樹的二叉查找快速的找到鍵值對。key的類型滿足ECMA標準中要求的類型。TreeMap中的鍵值是有序存儲的。TreeMap底層基于紅黑樹實現(xiàn),可以進行快速的插入和刪除。TreeMap進行增、刪、改、查操作的相關API如下:
4. TreeSet
TreeSet可用來存儲一系列值的集合,存儲元素中value是唯一的。TreeSet依據(jù)泛型定義,集合中的value值是有序的,TreeSet的底層是一棵二叉樹,可以通過樹的二叉查找快速的找到該value值,value的類型滿足ECMA標準中要求的類型。TreeSet中的值是有序存儲的。TreeSet底層基于紅黑樹實現(xiàn),可以進行快速的插入和刪除。TreeSet進行增、刪、改、查操作的相關API如下:
5. LightWeightMap
LigthWeightMap可用來存儲具有關聯(lián)關系的key-value鍵值對集合,存儲元素中key是唯一的,每個key會對應一個value值。LigthWeightMap依據(jù)泛型定義,采用更加輕量級的結構,集合中的key值的查找依賴于hash值以及二分查找算法,通過一個數(shù)組存儲hash值,然后映射到其他數(shù)組中的key值以及value值,key的類型滿足ECMA標準中要求的類型。
初始默認容量大小為8,每次擴容大小為原始容量的2倍。LigthWeightMap底層標識唯一key通過hash實現(xiàn),其沖突策略為線性探測法,查找策略基于二分查找法。LigthWeightMap進行增、刪、改、查操作的相關API如下:
6. LightWeightSet
LigthWeightSet可用來存儲一系列值的集合,存儲元素中value是唯一的。LigthWeightSet依據(jù)泛型定義,采用更加輕量級的結構,初始默認容量大小為8,每次擴容大小為原始容量的2倍。集合中的value值的查找依賴于hash以及二分查找算法,通過一個數(shù)組存儲hash值,然后映射到其他數(shù)組中的value值,value的類型滿足ECMA標準中要求的類型。
LigthWeightSet底層標識唯一value基于hash實現(xiàn),其沖突策略為線性探測法,查找策略基于二分查找法。LigthWeightSet進行增、刪、改、查操作的相關API如下:
7. PlainArray
PlainArray可用來存儲具有關聯(lián)關系的鍵值對集合,存儲元素中key是唯一的,并且對于PlainArray來說,其key的類型為number類型。每個key會對應一個value值,類型依據(jù)泛型的定義,PlainArray采用更加輕量級的結構,集合中的key值的查找依賴于二分查找算法,然后映射到其他數(shù)組中的value值。
初始默認容量大小為16,每次擴容大小為原始容量的2倍。PlainArray的查找策略基于二分查找法。PlainArray進行增、刪、改、查操作的相關API如下:
二、容器類的實現(xiàn)
下面我們將以ArrayList為例,為大家介紹,容器類的實現(xiàn)。包括容器類的初始化、容器類的接口調用、容器類對象模型的構建以及攔截器處理。
容器類初始化
在方舟開發(fā)框架中,通過NAPI的統(tǒng)一框架對外層提供容器類。下面,我們將以ArrayList為例,介紹基于NAPI的容器類的加載。如下圖所示,是容器類初始化流程,在NAPI加載的過程中,會通過ArkPrivate.Load接口加載對應的容器類。ArrayList在引擎中會初始化Constructor以及Prototype并返回,最后應用側可以獲得該容器類并使用。
圖1 容器類初始化流程
容器類接口調用
在方舟開發(fā)框架中,容器類API的調用流程如圖2所示,用戶先通過new ArrayList進入引擎得到對應的arraylist對象,然后可以通過add接口向對象中添加元素,元素最終會添加到一片和該arraylist綁定的內存空間。可以通過[]操作符進行元素獲取,對于容器類而言,引擎會直接通過快速路徑訪問到元素存儲位置,返回該值。
圖2 容器類API的調用流程
容器類對象模型
在方舟開發(fā)框架中,構造容器類對象模型的流程如下圖所示,在運行時禁止再向對象上添加Properties屬性,ArrayList借用對象模型中的elements位置存儲元素。
圖3 容器類對象模型的構造流程
實現(xiàn)說明:通過elements存儲數(shù)組元素,Length為數(shù)組中元素個數(shù),數(shù)組Capatity可以通過elements的長度獲取。
擴容策略:ArrayList –> 1.5倍
初始分配容量:ArrayList -> 10
(注:TS中的實現(xiàn),擴容策略及初始分配容量不感知)
攔截器處理
攔截器處理,是指通過禁止掉一些影響對象行為的操作,比如delete、setPrototype等,在運行時(Runtime)維護一個高效的容器類對象。如圖4所示,以ArrayList為例,ArkCompiler內部攔截的操作主要涉及DeleteProperty、DefineProperty、GetProperty、SetPrototype、GetOwnPropertyKeys、HasProperty等操作限制數(shù)組的holy添加,以及更改屬性的attributes等操作,保證了不需要做JSArray必須做的holy 判斷、writable 判斷等操作。
圖4 攔截器處理
HarmonyOS與OpenHarmony鴻蒙文檔籽料:mau123789是v直接拿
三、容器類API的使用
通過上文的介紹,相信大家對容器類已經(jīng)有了比較深刻的認識。那么,我們怎么使用容器類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)); // 訪問元素
審核編輯 黃宇
-
API
+關注
關注
2文章
1505瀏覽量
62178 -
鴻蒙
+關注
關注
57文章
2371瀏覽量
42911
發(fā)布評論請先 登錄
相關推薦
評論