1# Nonlinear Containers 2 3 4Nonlinear containers, underpinned by hash tables or red-black trees, implement a data structure that enables quick lookup operations. There are several types of nonlinear containers: HashMap, HashSet, TreeMap, TreeSet, LightWeightMap, LightWeightSet, and PlainArray. The types of **key** and **value** in nonlinear containers comply with the ECMA standard. 5 6## Comparison of Nonlinear Container Types 7 8| Type| Characteristics and Recommended Use Cases| 9| --------- | ------- | 10| HashMap | Stores a collection of key-value (KV) pairs with unique keys. It uses the hash code of the key to determine the storage location, offering fast access but no custom sorting. It is recommended for scenarios requiring quick storage, retrieval, and removal of KV pairs.| 11| HashSet | Stores a collection of unique values. It uses the hash code of the value to determine the storage location. It allows null values but does not support custom sorting. It is useful for creating non-redundant collections or removing duplicates.| 12| TreeMap | Stores a collection of KV pairs with unique keys. It allows users to customize sorting methods. It is suitable for scenarios requiring ordered storage of KV pairs.| 13| TreeSet | Stores a collection of unique values. It allows users to customize sorting methods but does not recommend storing null values. It is suitable for scenarios requiring ordered storage of collections.| 14| LightWeightMap | Stores a collection of KV pairs with unique keys. It uses a more lightweight structure, occupying less memory. It is recommended for scenarios with limited memory and the need to store KV pairs.| 15| LightWeightSet | Stores a collection of unique values. It uses a more lightweight structure, occupying less memory. It is useful for creating non-redundant collections or removing duplicates.| 16| PlainArray | Stores a collection of KV pairs with unique keys, where keys are of the number type. It uses a lightweight structure and a binary search algorithm for key lookup. It is suitable for storing KV pairs with number-type keys.| 17 18## HashMap 19 20[HashMap](../reference/apis-arkts/js-apis-hashmap.md) is used to store a collection of KV pairs with unique keys. Each key corresponds to a value. 21 22Defined by generics, HashMap uses the hash code of the key to determine the storage location, enabling quick access to KV pairs. The initial capacity is 16, and it supports dynamic resizing, doubling its size each time. HashMap is implemented using a hash table with a chain address conflict resolution strategy. 23 24HashMap 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. HashMap takes **key** and **value** as input parameters. 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 30Common APIs for adding, removing, modifying, and accessing elements in HashMap are as follows: 31 32| Operation| API| Description| 33| --------- | ------- | ------- | 34| Adding elements| set(key: K, value: V) | Adds a KV pair.| 35| Accessing elements| get(key: K) | Obtains the value corresponding to the specified key.| 36| Accessing elements| keys() | Returns an iterator that contains all the keys in the map.| 37| Accessing elements| values() | Returns an iterator that contains all the values in the map.| 38| Accessing elements| entries() | Returns an iterator that contains all the KV pairs in the map.| 39| Accessing elements| forEach(callbackFn: (value?: V, key?: K, map?: HashMap<K, V>) => void, thisArg?: Object) | Iterates over all elements in the map.| 40| Accessing elements| \[Symbol.iterator]():IterableIterator<[K,V]> | Creates an iterator for data access.| 41| Modifying elements| replace(key: K, newValue: V) | Modifies the value corresponding to the specified key.| 42| Modifying elements| forEach(callbackFn: (value?: V, key?: K, map?: HashMap<K, V>) => void, thisArg?: Object) | Modifies all elements in the map through iteration.| 43| Removing elements| remove(key: K) | Removes the KV pair matching the specified key from the map.| 44| Removing elements| clear() | Clears the entire map.| 45 46## HashSet 47 48[HashSet](../reference/apis-arkts/js-apis-hashset.md) is used to store a collection of unique values. 49 50Defined by generics, HashSet uses the hash code of the value to determine the storage location, enabling quick access to the value. The initial capacity is 16, and it supports dynamic resizing, doubling its size each time. 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 underlying data structure is consistent with HashMap. 51 52Compared with [TreeSet](../reference/apis-arkts/js-apis-treeset.md), which stores data in an ordered manner and allows users to define sorting functions, HashSet stores data in an unordered manner and does not support custom sorting. Neither allows duplicate elements, but HashSet permits null values, whereas TreeSet does not recommend storing null values as it may affect sorting results. 53 54You are advised to use HashSet when you need to create non-redundant collections or remove duplicates. 55 56Common APIs for adding, removing, modifying, and accessing elements in HashSet are as follows: 57 58| Operation| API| Description| 59| --------- | ------- | ------- | 60| Adding elements| add(value: T) | Adds a value.| 61| Accessing elements| values() | Returns an iterator that contains all the values in the set.| 62| Accessing elements| entries() | Returns an iterator object containing array-like KV pairs, where both keys and values are the same.| 63| Accessing elements| forEach(callbackFn: (value?: T, key?: T, set?: HashSet\<T>) => void, thisArg?: Object) | Iterates over all elements in the set.| 64| Accessing elements| \[Symbol.iterator]():IterableIterator<T> | Creates an iterator for data access.| 65| Modifying elements| forEach(callbackFn: (value?: T, key?: T, set?: HashSet\<T>) => void, thisArg?: Object) | Modifies all elements in the set through iteration.| 66| Removing elements| remove(value: T) | Removes the matching value from the set.| 67| Removing elements| clear() | Clears the entire set.| 68 69## TreeMap 70 71[TreeMap](../reference/apis-arkts/js-apis-treemap.md) is used to store a collection of KV pairs with unique keys. Each key corresponds to a value. 72 73Defined by generics, TreeMap stores keys in an ordered manner. TreeMap is implemented using a red-black tree, enabling fast insertion and removal. The type of **key** complies with the ECMA standard. 74 75Compared with [HashMap](../reference/apis-arkts/js-apis-hashmap.md), which provides faster access based on the key's hash code, TreeMap is ordered and thus less efficient. 76 77You are advised to use TreeMap when you need to store KV pairs in sorted order. 78 79Common APIs for adding, removing, modifying, and accessing elements in TreeMap are as follows: 80 81| Operation| API| Description| 82| --------- | ------- | ------- | 83| Adding elements| set(key: K, value: V) | Adds a KV pair.| 84| Accessing elements| get(key: K) | Obtains the value corresponding to the specified key.| 85| Accessing elements| getFirstKey() | Obtains the first key in the map.| 86| Accessing elements| getLastKey() | Obtains the last key in the map.| 87| Accessing elements| keys() | Returns an iterator that contains all the keys in the map.| 88| Accessing elements| values() | Returns an iterator that contains all the values in the map.| 89| Accessing elements| entries() | Returns an iterator that contains all the KV pairs in the map.| 90| Accessing elements| forEach(callbackFn: (value?: V, key?: K, map?: TreeMap<K, V>) => void, thisArg?: Object) | Iterates over all elements in the map.| 91| Accessing elements| \[Symbol.iterator]():IterableIterator<[K,V]> | Creates an iterator for data access.| 92| Modifying elements| replace(key: K, newValue: V) | Modifies the value corresponding to the specified key.| 93| Modifying elements| forEach(callbackFn: (value?: V, key?: K, map?: TreeMap<K, V>) => void, thisArg?: Object) | Modifies all elements in the map through iteration.| 94| Removing elements| remove(key: K) | Removes the KV pair matching the specified key from the map.| 95| Removing elements| clear() | Clears the entire map.| 96 97## TreeSet 98 99[TreeSet](../reference/apis-arkts/js-apis-treeset.md) is used to store a collection of unique values. 100 101Defined by generics, TreeSet stores values in an ordered manner. TreeSet is implemented using a red-black tree, enabling fast insertion and removal. The type of **value** complies with the ECMA standard. 102 103TreeSet is based on [TreeMap](../reference/apis-arkts/js-apis-treemap.md) and processes only the **value** object. It allows for ordered storage of a collection of values and can be sorted according to a custom sorting function. 104 105Compared with [HashSet](../reference/apis-arkts/js-apis-hashset.md), which stores data in an unordered manner, TreeSet stores data in an ordered manner. Neither allows duplicate elements, but HashSet permits null values, whereas TreeSet does not recommend storing null values as it may affect sorting results. 106 107You are advised to use TreeSet when you need to store data in sorted order. 108 109Common APIs for adding, removing, modifying, and accessing elements in TreeSet are as follows: 110 111| Operation| API| Description| 112| --------- | ------- | ------- | 113| Adding elements| add(value: T) | Adds a value.| 114| Accessing elements| values() | Returns an iterator that contains all the values in the set.| 115| Accessing elements| entries() | Returns an iterator object containing array-like KV pairs, where both keys and values are the same.| 116| Accessing elements| getFirstValue() | Obtains the first value in the set.| 117| Accessing elements| getLastValue() | Obtains the last value in the set.| 118| Accessing elements| forEach(callbackFn: (value?: T, key?: T, set?: TreeSet\<T>) => void, thisArg?: Object) | Iterates over all elements in the set.| 119| Accessing elements| \[Symbol.iterator]():IterableIterator<T> | Creates an iterator for data access.| 120| Modifying elements| forEach(callbackFn: (value?: T, key?: T, set?: TreeSet\<T>) => void, thisArg?: Object) | Modifies all elements in the set through iteration.| 121| Removing elements| remove(value: T) | Removes the matching value from the set.| 122| Removing elements| clear() | Clears the entire set.| 123 124## LightWeightMap 125 126[LightWeightMap](../reference/apis-arkts/js-apis-lightweightmap.md) is used to store a collection of KV pairs with unique keys. Each key corresponds to a value. Defined by generics, LightWeightMap uses a more lightweight structure. The underlying structure uses hash codes to identify unique keys, with a conflict resolution strategy of linear probing. The lookup of keys relies on hash codes and binary search algorithms, storing hash codes in an array and mapping them to **key** and **value** values in other arrays. The type of **key** complies with the ECMA standard. 127 128The default initial capacity is 8, and it supports dynamic resizing, doubling its size each time. 129 130LightWeightMap and [HashMap](../reference/apis-arkts/js-apis-hashmap.md) are both used to store KV pairs, but LightWeightMap occupies less memory. 131 132You are advised to use LightWeightMap when you need to store and access KV pairs. 133 134Common APIs for adding, removing, modifying, and accessing elements in LightWeightMap are as follows: 135 136| Operation| API| Description| 137| --------- | ------- | ------- | 138| Adding elements| set(key: K, value: V) | Adds a KV pair.| 139| Accessing elements| get(key: K) | Obtains the value corresponding to the specified key.| 140| Accessing elements| getIndexOfKey(key: K) | Obtains the index of the specified key in the map.| 141| Accessing elements| getIndexOfValue(value: V) | Obtains the index of the first occurrence of the specified value in the map.| 142| Accessing elements| keys() | Returns an iterator that contains all the keys in the map.| 143| Accessing elements| values() | Returns an iterator that contains all the values in the map.| 144| Accessing elements| entries() | Returns an iterator that contains all the KV pairs in the map.| 145| Accessing elements| getKeyAt(index: number) | Obtains the key at the specified index.| 146| Accessing elements| getValueAt(index: number) | Obtains the value at the specified index.| 147| Accessing elements| forEach(callbackFn: (value?: V, key?: K, map?: LightWeightMap<K, V>) => void, thisArg?: Object) | Iterates over all elements in the map.| 148| Accessing elements| \[Symbol.iterator]():IterableIterator<[K,V]> | Creates an iterator for data access.| 149| Modifying elements| setValueAt(index: number, newValue: V) | Modifies the value at the specified index.| 150| Modifying elements| forEach(callbackFn: (value?: V, key?: K, map?: LightWeightMap<K, V>) => void, thisArg?: Object) | Modifies all elements in the map through iteration.| 151| Removing elements| remove(key: K) | Removes the KV pair matching the specified key from the map.| 152| Removing elements| removeAt(index: number) | Removes the KV pair at the specified index from the map.| 153| Removing elements| clear() | Clears the entire map.| 154 155## LightWeightSet 156 157[LightWeightSet](../reference/apis-arkts/js-apis-lightweightset.md) is used to store a collection of unique values. 158 159Defined by generics, LightWeightSet uses a more lightweight structure. The default initial capacity is 8, and it supports dynamic resizing, doubling its size each time. The lookup of values relies on hash codes and binary search algorithms, storing hash codes in an array and mapping them to values in other arrays. The type of **value** complies with the ECMA standard. 160 161LightWeightSet identifies unique values based on hash at the underlying layer, with a conflict resolution strategy of linear probing and a lookup strategy based on binary search. 162 163LightWeightSet and [HashSet](../reference/apis-arkts/js-apis-hashset.md) are both used to store unique values, but LightWeightSet occupies less memory. 164 165You are advised to use LightWeightSet when you need a collection that contains unique elements or need to deduplicate a collection with limited memory. 166 167Common APIs for adding, removing, modifying, and accessing elements in LightWeightSet are as follows: 168 169| Operation| API| Description| 170| --------- | ------- | ------- | 171| Adding elements| add(obj: T) | Adds a value.| 172| Accessing elements| getIndexOf(key: T) | Obtains the index corresponding to the specified key.| 173| Accessing elements| getValueAt(index: number) | Obtains the value at the specified index.| 174| Accessing elements| values() | Returns an iterator that contains all the values in the set.| 175| Accessing elements| entries() | Returns an iterator object containing array-like KV pairs, where both keys and values are the same.| 176| Accessing elements| forEach(callbackFn: (value?: T, key?: T, set?: LightWeightSet\<T>) => void, thisArg?: Object) | Iterates over all elements in the set.| 177| Accessing elements| \[Symbol.iterator]():IterableIterator<T> | Creates an iterator for data access.| 178| Modifying elements| forEach(callbackFn: (value?: T, key?: T, set?: LightWeightSet\<T>) => void, thisArg?: Object) | Modifies all elements in the set through iteration.| 179| Removing elements| remove(key: K) | Removes the KV pair matching the specified key from the set.| 180| Removing elements| removeAt(index: number) | Removes the value at the specified index from the set.| 181| Removing elements| clear() | Clears the entire set.| 182 183## PlainArray 184 185[PlainArray](../reference/apis-arkts/js-apis-plainarray.md) is used to store a collection of KV pairs with unique keys, where keys are of the number type. Each key corresponds to a value. Defined by generics, PlainArray uses a more lightweight structure, with key lookup relying on binary search algorithms and mapping to **value** values in other arrays. 186 187The default initial capacity is 16, and it supports dynamic resizing, doubling its size each time. 188 189PlainArray and [LightWeightMap](../reference/apis-arkts/js-apis-lightweightmap.md) are both used to store KV pairs with a lightweight structure, but PlainArray's keys can only be of the number type. 190 191You are advised to use PlainArray when you need to store KV pairs whose keys are of the number type. 192 193Common APIs for adding, removing, modifying, and accessing elements in PlainArray are as follows: 194 195| Operation| API| Description| 196| --------- | ------- | ------- | 197| Adding elements| add(key: number,value: T) | Adds a KV pair.| 198| Accessing elements| get(key: number) | Obtains the value corresponding to the specified key.| 199| Accessing elements| getIndexOfKey(key: number) | Obtains the index of the specified key in the PlainArray.| 200| Accessing elements| getIndexOfValue(value: T) | Obtains the index of the first occurrence of the specified value in the PlainArray.| 201| Accessing elements| getKeyAt(index: number) | Obtains the key at the specified index.| 202| Accessing elements| getValueAt(index: number) | Obtains the value at the specified index.| 203| Accessing elements| forEach(callbackFn: (value: T, index?: number, PlainArray?: PlainArray\<T>) => void, thisArg?: Object) | Iterates over all elements in the PlainArray.| 204| Accessing elements| \[Symbol.iterator]():IterableIterator<[number, T]> | Creates an iterator for data access.| 205| Modifying elements| setValueAt(index:number, value: T) | Modifies the value at the specified index.| 206| Modifying elements| forEach(callbackFn: (value: T, index?: number, PlainArray?: PlainArray\<T>) => void, thisArg?: Object) | Modifies all elements in the PlainArray through iteration.| 207| Removing elements| remove(key: number) | Removes the KV pair matching the specified key.| 208| Removing elements| removeAt(index: number) | Removes the KV pair at the specified index.| 209| Removing elements| removeRangeFrom(index: number, size: number) | Removes elements within the specified range in the PlainArray.| 210| Removing elements| clear() | Clears the entire PlainArray.| 211 212## Use of Nonlinear Containers 213 214Here are usage examples for common nonlinear containers, including HashMap, TreeMap, LightWeightMap, and PlainArray, covering importing modules, adding elements, accessing elements, and modifying elements. The example code is as follows: 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 with key 'a' and value 123. 223let hashMap2: HashMap<number, number> = new HashMap(); 224hashMap2.set(4, 123); // Add an element with key 4 and value 123. 225console.info(`result: ${hashMap2.hasKey(4)}`); // Check whether an element with key 4 exists. Output: result: true 226console.info(`result: ${hashMap1.get('a')}`); // Access an element with key '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 with key 'a' and value 123. 233treeMap.set('6', 356); // Add an element with key '6' and value 356. 234console.info(`result: ${treeMap.get('a')}`); // Access an element with key '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 with key 'x' and value 123. 243lightWeightMap.set('8', 356); // Add an element with key '8' and value 356. 244console.info(`result: ${lightWeightMap.get('a')}`); // Access an element with key 'a'. Output: result: undefined 245console.info(`result: ${lightWeightMap.get('x')}`); // Obtain the value of the element with key 'x'. Output: result: 123 246console.info(`result: ${lightWeightMap.getIndexOfKey('8')}`); // Obtain the index of the element with key '8'. 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 with key 1 and value 'sdd'. 253plainArray.add(2, 'sff'); // Add an element with key 2 and value 'sff'. 254console.info(`result: ${plainArray.get(1)}`); // Obtain the value of the element with key 1. Output: result: sdd 255console.info(`result: ${plainArray.getKeyAt(1)}`); // Obtain the key of the element at index 1. Output: result: 2 256``` 257