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<[K,V]> | 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<T> | 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<[K,V]> | 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<T> | 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<[K,V]> | 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<T> | 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<[number, T]> | 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