HarmonyOS 鸿蒙非线性容器特性及使用场景
HarmonyOS 鸿蒙非线性容器特性及使用场景
<markdown _ngcontent-cur-c237="" class="markdownPreContainer">
HarmonyOS 非线性容器特性及使用场景
非线性容器实现能快速查找的数据结构,其底层通过 hash 或者红黑树实现,包括 HashMap、HashSet、TreeMap、TreeSet、LightWeightMap、LightWeightSet、PlainArray 七种。非线性容器中的 key 及 value 的类型均满足 ECMA 标准。
HashMap
HashMap 可用来存储具有关联关系的 key-value 键值对集合,存储元素中 key 是唯一的,每个 key 会对应一个 value 值。
HashMap 依据泛型定义,集合中通过 key 的 hash 值确定其存储位置,从而快速找到键值对。HashMap 的初始容量大小为 16,并支持动态扩容,每次扩容大小为原始容量的 2 倍。HashMap 底层基于 HashTable 实现,冲突策略采用链地址法。
HashMap 和 TreeMap 相比,HashMap 依据键的 hashCode 存取数据,访问速度较快。而 TreeMap 是有序存取,效率较低。
HashSet 基于 HashMap 实现。HashMap 的输入参数由 key、value 两个值组成。在 HashSet 中,只对 value 对象进行处理。
需要快速存取、删除以及插入键值对数据时,推荐使用 HashMap。
HashMap 进行增、删、改、查操作的常用 API 如下:
操作 | 描述 |
---|---|
增加元素 | 通过 set (key: K, value: V) 函数每次在 HashMap 增加一个键值对。 |
访问元素 | 通过 get (key: K) 获取 key 对应的 value 值。 |
通过 keys () 返回一个迭代器对象,包含 map 中的所有 key 值。 | |
通过 values () 返回一个迭代器对象,包含 map 中的所有 value 值。 | |
通过 entries () 返回一个迭代器对象,包含 map 中的所有键值对。 | |
forEach (callbackFn: (value?: V, key?: K, map?: HashMap<K, V>) => void, thisArg?: Object) 访问整个 map 的元素。 | |
通过 Symbol.iterator:IterableIterator<[K,V]> 迭代器进行数据访问。 | |
修改元素 | 通过 replace (key: K, newValue: V) 对指定 key 对应的 value 值进行修改操作。 |
通过 forEach (callbackFn: (value?: V, key?: K, map?: HashMap<K, V>) => void, thisArg?: Object) 对 map 中元素进行修改操作。 | |
删除元素 | 通过 remove (key: K) 对 map 中匹配到的键值对进行删除操作。 |
通过 clear () 清空整个 map 集合。 |
HashSet
HashSet 可用来存储一系列值的集合,存储元素中 value 是唯一的。
HashSet 依据泛型定义,集合中通过 value 的 hash 值确定其存储位置,从而快速找到该值。HashSet 初始容量大小为 16,支持动态扩容,每次扩容大小为原始容量的 2 倍。value 的类型满足 ECMA 标准中要求的类型。HashSet 底层数据结构基于 HashTable 实现,冲突策略采用链地址法。
HashSet 基于 HashMap 实现。在 HashSet 中,只对 value 对象进行处理。
HashSet 和 TreeSet 相比,HashSet 中的数据无序存放,即存放元素的顺序和取出的顺序不一致,而 TreeSet 是有序存放。它们集合中的元素都不允许重复,但 HashSet 允许放入 null 值,TreeSet 不允许。
可以利用 HashSet 不重复的特性,当需要不重复的集合或需要去重某个集合的时候使用。
HashSet 进行增、删、改、查操作的常用 API 如下:
操作 | 描述 |
---|---|
增加元素 | 通过 add (value: T) 函数每次在 HashSet 增加一个值。 |
访问元素 | 通过 values () 返回一个迭代器对象,包含 set 中的所有 value 值。 |
通过 entries () 返回一个迭代器对象,包含类似键值对的数组,键值都是 value。 | |
通过 forEach (callbackFn: (value?: T, key?: T, set?: HashSet) => void, thisArg?: Object) 访问整个 set 的元素。 | |
通过 Symbol.iterator:IterableIterator 迭代器进行数据访问。 | |
修改元素 | 通过 forEach (callbackFn: (value?: T, key?: T, set?: HashSet) => void, thisArg?: Object) 对 set 中 value 进行修改操作。 |
删除元素 | 通过 remove (value: T) 对 set 中匹配到的值进行删除操作。 |
通过 clear () 清空整个 set 集合。 |
TreeMap
TreeMap 可用来存储具有关联关系的 key-value 键值对集合,存储元素中 key 是唯一的,每个 key 会对应一个 value 值。
TreeMap 依据泛型定义,集合中的 key 值是有序的,TreeMap 的底层是一棵二叉树,可以通过树的二叉查找快速的找到键值对。key 的类型满足 ECMA 标准中要求的类型。TreeMap 中的键值是有序存储的。TreeMap 底层基于红黑树实现,可以进行快速的插入和删除。
TreeMap 和 HashMap 相比,HashMap 依据键的 hashCode 存取数据,访问速度较快。而 TreeMap 是有序存取,效率较低。
一般需要存储有序键值对的场景,可以使用 TreeMap。
TreeMap 进行增、删、改、查操作的常用 API 如下:
操作 | 描述 |
---|---|
增加元素 | 通过 set (key: K,value: V) 函数每次在 TreeMap 增加一个键值对。 |
访问元素 | 通过 get (key: K) 获取 key 对应的 value 值。 |
通过 getFirstKey () 获取 map 中排在首位的 key 值。 | |
通过 getLastKey () 获取 map 中排在未位的 key 值。 | |
通过 keys () 返回一个迭代器对象,包含 map 中的所有 key 值。 | |
通过 values () 返回一个迭代器对象,包含 map 中的所有 value 值。 | |
通过 entries () 返回一个迭代器对象,包含 map 中的所有键值对。 | |
通过 forEach (callbackFn: (value?: V, key?: K, map?: TreeMap<K, V>) => void, thisArg?: Object) 访问整个 map 的元素。 | |
通过 Symbol.iterator:IterableIterator<[K,V]> 迭代器进行数据访问。 | |
修改元素 | 通过 replace (key: K,newValue: V) 对指定 key 对应的 value 值进行修改操作。 |
通过 forEach (callbackFn: (value?: V, key?: K, map?: TreeMap<K, V>) => void, thisArg?: Object) 对 map 中元素进行修改操作。 | |
删除元素 | 通过 remove (key: K) 对 map 中匹配到的键值对进行删除操作。 |
通过 clear () 清空整个 map 集合。 |
TreeSet
TreeSet 可用来存储一系列值的集合,存储元素中 value 是唯一的。
TreeSet 依据泛型定义,集合中的 value 值是有序的,TreeSet 的底层是一棵二叉树,可以通过树的二叉查找快速的找到该 value 值,value 的类型满足 ECMA 标准中要求的类型。TreeSet 中的值是有序存储的。TreeSet 底层基于红黑树实现,可以进行快速的插入和删除。
TreeSet 基于 TreeMap 实现,在 TreeSet 中,只对 value 对象进行处理。TreeSet 可用于存储一系列值的集合,元素中 value 唯一且有序。
TreeSet 和 HashSet 相比,HashSet 中的数据无序存放,而 TreeSet 是有序存放。它们集合中的元素都不允许重复,但 HashSet 允许放入 null 值,TreeSet 不允许。
一般需要存储有序集合的场景,可以使用 TreeSet。
TreeSet 进行增、删、改、查操作的常用 API 如下:
操作 | 描述 |
---|---|
增加元素 | 通过 add (value: T) 函数每次在 HashSet 增加一个值。 |
访问元素 | 通过 values () 返回一个迭代器对象,包含 set 中的所有 value 值。 |
通过 entries () 返回一个迭代器对象,包含类似键值对的数组,键值都是 value。 | |
通过 getFirstValue () 获取 set 中排在首位的 value 值。 | |
通过 getLastValue () 获取 set 中排在未位的 value 值。 | |
通过 forEach (callbackFn: (value?: T, key?: T, set?: TreeSet) => void, thisArg?: Object) 访问整个 set 的元素。 | |
通过 Symbol.iterator:IterableIterator 迭代器进行数据访问。 | |
修改元素 | 通过 forEach (callbackFn: (value?: T, key?: T, set?: TreeSet) => void, thisArg?: Object) 对 set 中 value 进行修改操作。 |
删除元素 | 通过 remove (value: T) 对 set 中匹配到的值进行删除操作。 |
通过 clear () 清空整个 set 集合。 |
LightWeightMap
LightWeightMap 可用来存储具有关联关系的 key-value 键值对集合,存储元素中 key 是唯一的,每个 key 会对应一个 value 值。LightWeightMap 依据泛型定义,采用更加轻量级的结构,底层标识唯一 key 通过 hash 实现,其冲突策略为线性探测法。集合中的 key 值的查找依赖于 hash 值以及二分查找算法,通过一个数组存储 hash 值,然后映射到其他数组中的 key 值以及 value 值,key 的类型满足 ECMA 标准中要求的类型。
初始默认容量大小为 8,每次扩容大小为原始容量的 2 倍。
LightWeightMap 和 HashMap 都是用来存储键值对的集合,LightWeightMap 占用内存更小。
当需要存取 key-value 键值对时,推荐使用占用内存更小的 LightWeightMap。
LightWeightMap 进行增、删、改、查操作的常用 API 如下:
操作 | 描述 |
---|---|
增加元素 | 通过 set (key: K,value: V) 函数每次在 LightWeightMap 增加一个键值对。 |
访问元素 | 通过 get (key: K) 获取 key 对应的 value 值。 |
通过 getIndexOfKey (key: K) 获取 map 中指定 key 的 index。 | |
通过 getIndexOfValue (value: V) 获取 map 中指定 value 出现的第一个的 index。 | |
通过 keys () 返回一个迭代器对象,包含 map 中的所有 key 值。 | |
通过 values () 返回一个迭代器对象,包含 map 中的所有 value 值。 | |
通过 entries () 返回一个迭代器对象,包含 map 中的所有键值对。 | |
通过 getKeyAt (index: number) 获取指定 index 对应的 key 值。 | |
通过 getValueAt (index: number) 获取指定 index 对应的 value 值。 | |
通过 forEach (callbackFn: (value?: V, key?: K, map?: LightWeightMap<K, V>) => void, thisArg?: Object) 访问整个 map 的元素 | |
通过 Symbol.iterator:IterableIterator<[K,V]> 迭代器进行数据访问。 | |
修改元素 | 通过 setValueAt (index: number, newValue: V) 对指定 index 对应的 value 值进行修改操作。 |
通过 forEach (callbackFn: (value?: V, key?: K, map?: LightWeightMap<K, V>) => void, thisArg?: Object) 对 map 中元素进行修改操作。 | |
删除元素 | 通过 remove (key: K) 对 map 中匹配到的键值对进行删除操作。 |
通过 removeAt (index: number) 对 map 中指定 index 的位置进行删除操作。 | |
通过 clear () 清空整个 map 集合。 |
LightWeightSet
LightWeightSet 可用来存储一系列值的集合,存储元素中 value 是唯一的。
LightWeightSet 依据泛型定义,采用更加轻量级的结构,初始默认容量大小为 8,每次扩容大小为原始容量的 2 倍。集合中的 value 值的查找依赖于 hash 以及二分查找算法,通过一个数组存储 hash 值,然后映射到其他数组中的 value 值,value 的类型满足 ECMA 标准中要求的类型。
LightWeightSet 底层标识唯一 value 基于 hash 实现,其冲突策略为线性探测法,查找策略基于二分查找法。
LightWeightSet 和 HashSet 都是用来存储键值的集合,LightWeightSet 的占用内存更小。
当需要存取某个集合或是对某个集合去重时,推荐使用占用内存更小的 LightWeightSet。
LightWeightSet 进行增、删、改、查操作的常用 API 如下:
操作 | 描述 |
---|---|
增加元素 | 通过 add (obj: T) 函数每次在 LightWeightSet 增加一个值。 |
访问元素 | 通过 getIndexOf (key: T) 获取对应的 index 值。 |
通过 values () 返回一个迭代器对象,包含 map 中的所有 value 值。 | |
通过 entries () 返回一个迭代器对象,包含 map 中的所有键值对。 | |
通过 getValueAt (index: number) 获取指定 index 对应的 value 值。 | |
通过 forEach (callbackFn: (value?: T, key?: T, set?: LightWeightSet) => void, thisArg?: Object) 访问整个 set 的元素。 | |
通过 Symbol.iterator:IterableIterator 迭代器进行数据访问。 | |
修改元素 | 通过 forEach (callbackFn: (value?: T, key?: T, set?: LightWeightSet) => void, thisArg?: Object) 对 set 中元素进行修改操作。 |
删除元素 | 通过 remove (key: K) 对 set 中匹配到的键值对进行删除操作。 |
通过 removeAt (index: number) 对 set 中指定 index 的位置进行删除操作。 | |
通过 clear () 清空整个 set 集合。 |
PlainArray
PlainArray 可用来存储具有关联关系的键值对集合,存储元素中 key 是唯一的,并且对于 PlainArray 来说,其 key 的类型为 number 类型。每个 key 会对应一个 value 值,类型依据泛型的定义,PlainArray 采用更加轻量级的结构,集合中的 key 值的查找依赖于二分查找算法,然后映射到其他数组中的 value 值。
初始默认容量大小为 16,每次扩容大小为原始容量的 2 倍。
PlainArray 和 LightWeightMap 都是用来存储键值对,且均采用轻量级结构,但 PlainArray 的 key 值类型只能为 number 类型。
当需要存储 key 值为 number 类型的键值对时,可以使用 PlainArray。
PlainArray 进行增、删、改、查操作的常用 API 如下:
操作 | 描述 |
---|---|
增加元素 | 通过 add (key: number,value: T) 函数每次在 PlainArray 增加一个键值对。 |
访问元素 | 通过 get (key: number) 获取 key 对应的 value 值。 |
通过 getIndexOfKey (key: number) 获取 PlainArray 中指定 key 的 index。 | |
通过 getIndexOfValue (value: T) 获取 PlainArray 中指定 value 的 index。 | |
通过 getKeyAt (index: number) 获取指定 index 对应的 key 值。 | |
通过 getValueAt (index: number) 获取指定 index 对应的 value 值。 | |
通过 forEach (callbackFn: (value: T, index?: number, PlainArray?: PlainArray) => void, thisArg?: Object) 访问整个 plainarray 的元素。 | |
通过 Symbol.iterator:IterableIterator<[number, T]> 迭代器进行数据访问。 | |
修改元素 | 通过 setValueAt (index:number, value: T) 对指定 index 对应的 value 值进行修改操作。 |
通过 forEach (callbackFn: (value: T, index?: number, PlainArray?: PlainArray) => void, thisArg?: Object) 对 plainarray 中元素进行修改操作。 | |
删除元素 | 通过 remove (key: number) 对 plainarray 中匹配到的键值对进行删除操作。 |
通过 removeAt (index: number) 对 plainarray 中指定 index 的位置进行删除操作。 | |
通过 removeRangeFrom (index: number, size: number) 对 plainarray 中指定范围内的元素进行删除操作。 | |
通过 clear () 清空整个 PlainArray 集合。 |
非线性容器的使用
此处列举常用的非线性容器 HashMap、TreeMap、LightWeightMap、PlainArray 的使用示例,包括导入模块、增加元素、访问元素及修改等操作,示例代码如下所示:
// HashMap
import HashMap from '@ohos.util.HashMap'; // 导入HashMap模块
let hashMap = new HashMap();
hashMap.set(‘a’, 123);
hashMap.set(4, 123); // 增加元素
console.info(result: ${hashMap.hasKey(<span class="hljs-number"><span class="hljs-number">4</span></span>)}
); // 判断是否含有某元素
console.info(result: ${hashMap.<span class="hljs-keyword"><span class="hljs-keyword">get</span></span>(<span class="hljs-string"><span class="hljs-string">'a'</span></span>)}
); // 访问元素
// TreeMap
import TreeMap from ‘@ohos.util.TreeMap’; // 导入TreeMap模块
let treeMap = new TreeMap();
treeMap.set(‘a’, 123);
treeMap.set(‘6’, 356); // 增加元素
console.info(result: ${treeMap.<span class="hljs-keyword"><span class="hljs-keyword">get</span></span>(<span class="hljs-string"><span class="hljs-string">'a'</span></span>)}
); // 访问元素
console.info(result: ${treeMap.getFirstKey()}
); // 访问首元素
console.info(result: ${treeMap.getLastKey()}
); // 访问尾元素
// LightWeightMap
import LightWeightMap from ‘@ohos.util.LightWeightMap’; // 导入LightWeightMap模块
let lightWeightMap = new LightWeightMap();
lightWeightMap.set(‘x’, 123);
lightWeightMap.set(‘8’, 356); // 增加元素
console.info(result: ${lightWeightMap.<span class="hljs-keyword"><span class="hljs-keyword">get</span></span>(<span class="hljs-string"><span class="hljs-string">'a'</span></span>)}
); // 访问元素
console.info(result: ${lightWeightMap.<span class="hljs-keyword"><span class="hljs-keyword">get</span></span>(<span class="hljs-string"><span class="hljs-string">'x'</span></span>)}
); // 访问元素
console.info(result: ${lightWeightMap.getIndexOfKey(<span class="hljs-string"><span class="hljs-string">'8'</span></span>)}
); // 访问元素
// PlainArray
import PlainArray from ‘@ohos.util.PlainArray’ // 导入PlainArray模块
let plainArray = new PlainArray();
plainArray.add(1, ‘sdd’);
plainArray.add(2, ‘sff’); // 增加元素
console.info(result: ${plainArray.<span class="hljs-keyword"><span class="hljs-keyword">get</span></span>(<span class="hljs-number"><span class="hljs-number">1</span></span>)}
); // 访问元素
console.info(result: ${plainArray.getKeyAt(<span class="hljs-number"><span class="hljs-number">1</span></span>)}
); // 访问元素
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
</markdown>
HarmonyOS的非线性容器特性主要体现在其底层通过hash或红黑树等数据结构实现快速查找。主要非线性容器包括HashMap、HashSet、TreeMap、TreeSet等,它们支持高效的数据存取、删除和插入操作。HashMap和HashSet适用于需要快速查找键值对或唯一值的场景,TreeMap和TreeSet则适用于需要保持元素有序的场景。这些容器广泛用于鸿蒙系统的多设备协同、数据管理等场景。如果问题依旧没法解决请加我微信,我的微信是itying888。