1# Nonlinear Containers
2
3
4Nonlinear containers, underpinned by hash tables or red-black trees, implement a data structure that enables quick search. There are several types of nonlinear containers: **HashMap**, **HashSet**, **TreeMap**, **TreeSet**, **LightWeightMap**, **LightWeightSet**, and **PlainArray**. The types of **key** and **value** in nonlinear containers must meet the ECMA standard.
5
6## Comparison of Non-linear Container Types
7
8| Class| Characteristics and Recommended Application Scenarios|
9| --------- | ------- |
10| HashMap | Stores a set of key-value pairs that have association relationships. The key in the storage element is unique, and the storage location is determined based on the hash value of the key. The access speed is fast, but the sorting cannot be customized. Recommended for quick access, insertion, and deletion of key-value pair data.|
11| HashSet | A set of values. Each value in a storage element is unique. The storage location is determined based on the hash of the value. Null values can be added, but the sorting cannot be customized. It can be used when a non-repeated collection is required or a collection needs to be deduplicated.|
12| TreeMap | Stores a set of key-value pairs that have association relationships. The key in the storage element is unique. You can customize the sorting method. Generally, this mode can be used in scenarios where key-value pairs need to be stored in sequence.|
13| TreeSet | A set of values. The values in the storage element are unique. You can customize the sorting method, but you are not advised to put null values. Generally, this method can be used in scenarios where collections need to be stored in sequence.|
14| LightWeightMap | Stores a set of key-value pairs that have association relationships. The key in the storage element is unique. The bottom layer uses a more lightweight structure and occupies less space. This mode is recommended when key-value pair data needs to be accessed and the memory is insufficient.|
15| LightWeightSet |  Stores a set of values. The values in the storage element are unique. The bottom layer uses a more lightweight structure and occupies less space. This method is recommended when you need a unique set or a set to be deduplicated.|
16| PlainArray | Stores a set of key-value pairs that have association relationships. The key in the storage element is unique. The bottom layer uses a more lightweight structure like LightWeightMap, and the key is of the number type. You are advised to use PlainArray when you need to store KV pairs whose keys are of the number type.|
17
18## HashMap
19
20[HashMap](../reference/apis-arkts/js-apis-hashmap.md) is used to store a set of associated key-value (KV) pairs. In a hash map, each key is unique and corresponds to a value.
21
22**HashMap** uses generics. In a hash map, a key is located based on its hash code. The initial capacity of a hash map is 16, and it has capacity doubled in each dynamic expansion. The bottom layer of **HashMap** is implemented based on a hash table. It uses chaining to avoid collisions in hash tables.
23
24**HashMap** is faster in accessing data than [TreeMap](../reference/apis-arkts/js-apis-treemap.md), because the former accesses the keys based on the hash codes, whereas the latter stores and accesses the keys in sorted order.
25
26[HashSet](../reference/apis-arkts/js-apis-hashset.md) is implemented based on **HashMap**. The input parameter of **HashMap** consists of **key** and **value**. In **HashSet**, only the **value** object is processed.
27
28You are advised to use **HashMap** when you need to quickly access, remove, and insert KV pairs.
29
30**HashMap** provides the following Create, Read, Update, and Delete (CRUD) APIs.
31
32| Operation| API| Description|
33| --------- | ------- | ------- |
34| Create| set(key: K, value: V) | Adds a key-value pair.|
35| Read| get(key: K) | Value corresponding to the target key.|
36| Read| keys() | Use **keys()** to return an iterator that contains all the keys in this container.|
37| Read| values() | Use **values()** to return an iterator that contains all the values in this container.|
38| Read| entries() | Use **entries()** to return an iterator that contains all the elements in this container.|
39| Read| forEach(callbackFn: (value?: V, key?: K, map?: HashMap<K, V>) => void, thisArg?: Object) | Traverses the elements of the entire map.|
40| Read| \[Symbol.iterator]():IterableIterator&lt;[K,V]&gt; | Creates an iterator for data access.|
41| Update| replace(key: K, newValue: V) | Value corresponding to the target key.|
42| Update| forEach(callbackFn: (value?: V, key?: K, map?: HashMap<K, V>) => void, thisArg?: Object) | Modify the elements of the entire map through traversal.|
43| Delete| remove(key: K) | Deletes the matched key-value pair from the map.|
44| Delete| clear() | Clears the entire map.|
45
46## HashSet
47
48[HashSet](../reference/apis-arkts/js-apis-hashset.md) is used to store a set of values, each of which is unique in a hash set.
49
50**HashSet** uses generics. In a hash set, a value is located based on its hash code. The initial capacity of a hash set is 16, and it has capacity doubled in each dynamic expansion. The type of **value** must comply with the ECMA standard. HashSet is implemented based on [HashMap](../reference/apis-arkts/js-apis-hashmap.md) and processes only the value object. The bottom-layer data structure is the same as that of HashMap.
51
52Compared with [TreeSet](../reference/apis-arkts/js-apis-treeset.md), data in HashSet is stored in an unordered manner, that is, users cannot specify the sorting mode. However, data in TreeSet is stored in an ordered manner, that is, elements can be sorted based on the sorting function specified by users. Both of them allow only unique elements. However, null values are allowed in **HashSet**, but not in **TreeSet**, because null values may affect the order of elements in the container.
53
54You are advised to use **HashSet** when you need a set that has only unique elements or need to deduplicate a set.
55
56**HashSet** provides the following CRUD APIs.
57
58| Operation| API| Description|
59| --------- | ------- | ------- |
60| Create| add(value: T) | Adds a value.|
61| Read| values() | Use **values()** to return an iterator that contains all the values in this container.|
62| Read| entries() | Use **entries()** to return an iterator that contains all the elements in this container.|
63| Read| forEach(callbackFn: (value?: T, key?: T, set?: HashSet\<T>) => void, thisArg?: Object) | Traverses and accesses the elements of the entire set.|
64| Read| \[Symbol.iterator]():IterableIterator&lt;T&gt; | Creates an iterator for data access.|
65| Update| forEach(callbackFn: (value?: T, key?: T, set?: HashSet\<T>) => void, thisArg?: Object) | Modify the elements of the entire set through traversal.|
66| Delete| remove(value: T) | Deletes the matched value from the set.|
67| Delete| clear() | Clears the entire set.|
68
69## TreeMap
70
71[TreeMap](../reference/apis-arkts/js-apis-treemap.md) is used to store a set of associated KV pairs. In a tree map, each key is unique and corresponds to a value.
72
73**TreeMap** uses generics, and the keys in a tree map are ordered. The bottom layer of **TreeMap** is a binary tree, which supports quick search of KV pairs through the children (left child and right child) of the tree. The type of **key** must comply with the ECMA standard. Keys in a tree map are stored in order. The bottom layer of **TreeMap** is implemented based on the red-black tree and supports quick insertion and removal.
74
75[HashMap](../reference/apis-arkts/js-apis-hashmap.md) is faster in accessing data than **TreeMap**, because the former accesses the keys based on the hash codes, whereas the latter stores and accesses the keys in sorted order.
76
77You are advised to use **TreeMap** when you need to store KV pairs in sorted order.
78
79**TreeMap** provides the following CRUD APIs.
80
81| Operation| API| Description|
82| --------- | ------- | ------- |
83| Create| set(key: K, value: V) | Adds a key-value pair.|
84| Read| get(key: K) | Value corresponding to the target key.|
85| Read| getFirstKey() | Use **getFirstKey()** to obtain the first key in this container.|
86| Read| getLastKey() | Use **getLastKey()** to obtain the last key in this container.|
87| Read| keys() | Use **keys()** to return an iterator that contains all the keys in this container.|
88| Read| values() | Use **values()** to return an iterator that contains all the values in this container.|
89| Read| entries() | Use **entries()** to return an iterator that contains all the elements in this container.|
90| Read| forEach(callbackFn: (value?: V, key?: K, map?: TreeMap<K, V>) => void, thisArg?: Object) | Traverses the elements of the entire map.|
91| Read| \[Symbol.iterator]():IterableIterator&lt;[K,V]&gt; | Creates an iterator for data access.|
92| Update| replace(key: K, newValue: V) | Value corresponding to the target key.|
93| Update| forEach(callbackFn: (value?: V, key?: K, map?: TreeMap<K, V>) => void, thisArg?: Object) | Modify the elements of the entire map through traversal.|
94| Delete| remove(key: K) | Deletes the matched key-value pair from the map.|
95| Delete| clear() | Clears the entire map.|
96
97## TreeSet
98
99[TreeSet](../reference/apis-arkts/js-apis-treeset.md) is used to store a set of values, each of which is unique in a tree set.
100
101**TreeSet** uses generics, and the values in a tree set are ordered. The bottom layer of **TreeSet** is a binary tree, which supports quick search of a value through the children (left child and right child) of the tree. The type of **value** must meet the ECMA standard. Values in a tree set are stored in order. The bottom layer of **TreeSet** is implemented based on the red-black tree and supports quick insertion and removal.
102
103**TreeSet** is implemented based on [TreeMap](../reference/apis-arkts/js-apis-treemap.md). In **TreeSet**, only **value** objects are processed. A TreeSet can be used to store a set of values. The value in an element is unique and can be sorted based on the sorting function specified by the user.
104
105[HashSet](../reference/apis-arkts/js-apis-hashset.md) stores data in a random order, whereas **TreeSet** stores data in sorted order. Both of them allow only unique elements. However, null values are allowed in **HashSet**, but not in **TreeSet**, because null values may affect the order of elements in the container.
106
107You are advised to use **TreeSet** when you need to store data in sorted order.
108
109**TreeSet** provides the following CRUD APIs.
110
111| Operation| API| Description|
112| --------- | ------- | ------- |
113| Create| add(value: T) | Adds a value.|
114| Read| values() | Use **values()** to return an iterator that contains all the values in this container.|
115| Read| entries() | Use **entries()** to return an iterator that contains all the elements in this container.|
116| Read| getFirstValue() | Use **getFirstValue()** to obtain the first value in this container.|
117| Read| getLastValue() | Use **getLastValue()** to obtain the last value in this container.|
118| Read| forEach(callbackFn: (value?: T, key?: T, set?: TreeSet\<T>) => void, thisArg?: Object) | Traverses and accesses the elements of the entire set.|
119| Read| \[Symbol.iterator]():IterableIterator&lt;T&gt; | Creates an iterator for data access.|
120| Update| forEach(callbackFn: (value?: T, key?: T, set?: TreeSet\<T>) => void, thisArg?: Object) | Modify the elements of the entire set through traversal.|
121| Delete| remove(value: T) | Deletes the matched value from the set.|
122| Delete| clear() | Clears the entire set.|
123
124## LightWeightMap
125
126[LightWeightMap](../reference/apis-arkts/js-apis-lightweightmap.md) is used to store a set of associated KV pairs. In a lightweight map, each key is unique and corresponds to a value. **LightWeightMap** uses generics and a more lightweight structure. It uses the hash code to uniquely identify a key at the bottom layer. It uses linear probing to avoid collisions. In a lightweight map, a key is located by using the hash code and binary search algorithm. The hash code is stored in an array and mapped to a key and its value in another array. The type of **key** must comply with the ECMA standard.
127
128The default initial capacity of a lightweight map is 8, and it has capacity doubled in each expansion.
129
130Compared with [HashMap](../reference/apis-arkts/js-apis-hashmap.md), which can also store KV pairs, **LightWeightMap** occupies less memory.
131
132You are advised to use **LightWeightMap** when you need to store and access **KV pairs**.
133
134**LightWeightMap** provides the following CRUD APIs.
135
136| Operation| API| Description|
137| --------- | ------- | ------- |
138| Create| set(key: K, value: V) | Adds a key-value pair.|
139| Read| get(key: K) | Value corresponding to the target key.|
140| Read| getIndexOfKey(key: K) | Obtains the index of a specified key in a map.|
141| Read| getIndexOfValue(value: V) | Obtains the first index of a specified value in a map.|
142| Read| keys() | Use **keys()** to return an iterator that contains all the keys in this container.|
143| Read| values() | Use **values()** to return an iterator that contains all the values in this container.|
144| Read| entries() | Use **entries()** to return an iterator that contains all the elements in this container.|
145| Read| getKeyAt(index: number) | Pointer to the function used to obtain the cookie value of a specified URL.|
146| Read| getValueAt(index: number) | Pointer to the function used to obtain the cookie value of a specified URL.|
147| Read| forEach(callbackFn: (value?: V, key?: K, map?: LightWeightMap<K, V>) => void, thisArg?: Object) | Traverses the elements of the entire map.|
148| Read| \[Symbol.iterator]():IterableIterator&lt;[K,V]&gt; | Creates an iterator for data access.|
149| Update| setValueAt(index: number, newValue: V) | Modifies the value of a specified index.|
150| Update| forEach(callbackFn: (value?: V, key?: K, map?: LightWeightMap<K, V>) => void, thisArg?: Object) | Modify the elements of the entire map through traversal.|
151| Delete| remove(key: K) | Deletes the key-value pair that matches a specified key in a map.|
152| Delete| removeAt(index: number) | Removes a key-value pair with the specified key.|
153| Delete| clear() | Clears the entire map.|
154
155## LightWeightSet
156
157[LightWeightSet](../reference/apis-arkts/js-apis-lightweightset.md) is used to store a set of values, each of which is unique in a lightweight set.
158
159**LightWeightSet** uses generics and a lightweight structure. Its default initial capacity is 8, and it has capacity doubled in each expansion. In a lightweight set, a value is located by using the hash code and binary search algorithm. The hash code is stored in an array and mapped to a value in another array. The type of **value** must comply with the ECMA standard.
160
161**LightWeightSet** uses the hash code to uniquely identify a value at the bottom layer. It uses linear probing to avoid collisions and adopts the binary search algorithm.
162
163Compared with [HashSet](../reference/apis-arkts/js-apis-hashset.md), which can also store values, **LightWeightSet** occupies less memory.
164
165You are advised to use **LightWeightSet** when you need a set that has only unique elements or need to deduplicate a set.
166
167**LightWeightSet** provides the following CRUD APIs.
168
169| Operation| API| Description|
170| --------- | ------- | ------- |
171| Create| add(value: T) | Adds a value.|
172| Read| getIndexOf(key: T) | Key of the value to obtain.|
173| Read| getValueAt(index: number) | Pointer to the function used to obtain the cookie value of a specified URL.|
174| Read| values() | Use **values()** to return an iterator that contains all the values in this container.|
175| Read| entries() | Use **entries()** to return an iterator that contains all the elements in this container.|
176| Read| forEach(callbackFn: (value?: T, key?: T, set?: LightWeightSet\<T>) => void, thisArg?: Object) | Traverses and accesses the elements of the entire set.|
177| Read| \[Symbol.iterator]():IterableIterator&lt;T&gt; | Creates an iterator for data access.|
178| Update| forEach(callbackFn: (value?: T, key?: T, set?: LightWeightSet\<T>) => void, thisArg?: Object) | Modify the elements of the entire set through traversal.|
179| Delete| remove(key: K) | Deletes the matched key-value pair from the set.|
180| Delete| removeAt(index: number) | Deletes the value of a specified index from a set.|
181| Delete| clear() | Clears the entire set.|
182
183## PlainArray
184
185[PlainArray](../reference/apis-arkts/js-apis-plainarray.md) is used to store a set of associated KV pairs. In a plain array, each key is unique, corresponds to a value, and is of the number type. **PlainArray** uses generics and a more lightweight structure. In a plain array, a key is located by using the binary search algorithm and is mapped to a value in another array.
186
187The default initial capacity of a plain array is 16, and it has capacity doubled in each expansion.
188
189Both **PlainArray** and [LightWeightMap](../reference/apis-arkts/js-apis-lightweightmap.md) are used to store KV pairs in the lightweight structure. However, the key type of **PlainArray** can only be **number**.
190
191You are advised to use PlainArray when you need to store KV pairs whose keys are of the number type.
192
193**PlainArray** provides the following CRUD APIs.
194
195| Operation| API| Description|
196| --------- | ------- | ------- |
197| Create| add(key: number,value: T) | Adds a key-value pair.|
198| Read| get(key: number) | Value corresponding to the target key.|
199| Read| getIndexOfKey(key: number) | Obtains the index of a specified key in PlainArray.|
200| Read| getIndexOfValue(value: T) | Obtains the first index of a specified value in a PlainArray.|
201| Read| getKeyAt(index: number) | Pointer to the function used to obtain the cookie value of a specified URL.|
202| Read| getValueAt(index: number) | Pointer to the function used to obtain the cookie value of a specified URL.|
203| Read| forEach(callbackFn: (value: T, index?: number, PlainArray?: PlainArray\<T>) => void, thisArg?: Object) | Traverses the elements of the entire PlainArray.|
204| Read| \[Symbol.iterator]():IterableIterator&lt;[number, T]&gt; | Creates an iterator for data access.|
205| Update| setValueAt(index:number, value: T) | Modifies the value of a specified index.|
206| Update| forEach(callbackFn: (value: T, index?: number, PlainArray?: PlainArray\<T>) => void, thisArg?: Object) | Modify the elements of the entire PlainArray through traversal.|
207| Delete| remove(key: number) | Deletes the key-value pair that matches a specified key in PlainArray.|
208| Delete| removeAt(index: number) | Removes a key-value pair with the specified key.|
209| Delete| removeRangeFrom(index: number, size: number) | Deletes elements in a specified range from PlainArray.|
210| Delete| clear() | Clears the entire PlainArray.|
211
212## Use of Nonlinear Containers
213
214Refer to the code snippet below to add, access, and modify elements in **HashMap**, **TreeMap**, **LightWeightMap**, **Stack**, and **PlainArray**.
215
216
217```ts
218// HashMap
219import { HashMap } from '@kit.ArkTS'; // Import the HashMap module.
220
221let hashMap1: HashMap<string, number> = new HashMap();
222hashMap1.set ('a', 123); // Add an element whose key is'a' and value is 123.
223let hashMap2: HashMap<number, number> = new HashMap();
224hashMap2.set (4, 123); // Add an element whose key is 4 and value is 123.
225console.info ('result: ${hashMap2.hasKey (4) }'); // Check whether an element whose key is 4 exists. Output: result: true
226console.info ('result: ${hashMap1.get ('a') }'); // Element whose access key is'a'. Output: result: 123
227
228// TreeMap
229import { TreeMap } from '@kit.ArkTS'; // Import the TreeMap module.
230
231let treeMap: TreeMap<string, number> = new TreeMap();
232treeMap.set ('a', 123); // Add an element whose key is'a' and value is 123.
233treeMap.set ('6', 356); // Add an element whose key is '6' and value is 356.
234console.info ('result: ${treeMap.get ('a') }'); // Element whose access key is'a'. Output: result: 123
235console.info ('result: ${treeMap.getFirstKey () }'); // Access the first element. Output: result: 6
236console.info ('result: ${treeMap.getLastKey () }'); // Access the last element. Output: result: a
237
238// LightWeightMap
239import { LightWeightMap } from '@kit.ArkTS'; // Import the LightWeightMap module.
240
241let lightWeightMap: LightWeightMap<string, number> = new LightWeightMap();
242lightWeightMap.set ('x', 123); // Add an element whose key is'x' and value is 123.
243lightWeightMap.set ('8', 356); // Add an element whose key is '8' and value is 356.
244console.info ('result: ${lightWeightMap.get ('a') }'); // Element whose access key is'a'. Output: result: undefined
245console.info ('result: ${lightWeightMap.get ('x') }'); // Obtain the value of the element whose access key is 'x'. Output: result: 123
246console.info(`result: ${lightWeightMap.getIndexOfKey('8')}`); // accesses the element whose key is '8' and obtains its index. Output: result: 0
247
248// PlainArray
249import { PlainArray } from '@kit.ArkTS'; // Import the PlainArray module.
250
251let plainArray: PlainArray<string> = new PlainArray();
252plainArray.add (1,'sdd'); // Add an element whose key is 1 and value is'sdd'.
253plainArray.add (2, 'sff'); // Add an element whose key is 2 and value is'sff'.
254console.info ('result: ${plainArray.get (1) }'); // Access the element whose key is 1 to obtain the value. Output: result: sdd
255console.info ('result: ${plainArray.getKeyAt (1) }'); // Access the element whose index is 1 to obtain the key. Output: result: 2
256```
257