|
15 | 15 | //! standard implementations, it should be possible for two libraries to |
16 | 16 | //! communicate without significant data conversion. |
17 | 17 | //! |
18 | | -//! To get this out of the way: you should probably just use `Vec` or `HashMap`. |
| 18 | +//! To get this out of the way: you should probably just use [`Vec`] or [`HashMap`]. |
19 | 19 | //! These two collections cover most use cases for generic data storage and |
20 | 20 | //! processing. They are exceptionally good at doing what they do. All the other |
21 | 21 | //! collections in the standard library have specific use cases where they are |
|
25 | 25 | //! |
26 | 26 | //! Rust's collections can be grouped into four major categories: |
27 | 27 | //! |
28 | | -//! * Sequences: `Vec`, `VecDeque`, `LinkedList` |
29 | | -//! * Maps: `HashMap`, `BTreeMap` |
30 | | -//! * Sets: `HashSet`, `BTreeSet` |
31 | | -//! * Misc: `BinaryHeap` |
| 28 | +//! * Sequences: [`Vec`], [`VecDeque`], [`LinkedList`] |
| 29 | +//! * Maps: [`HashMap`], [`BTreeMap`] |
| 30 | +//! * Sets: [`HashSet`], [`BTreeSet`] |
| 31 | +//! * Misc: [`BinaryHeap`] |
32 | 32 | //! |
33 | 33 | //! # When Should You Use Which Collection? |
34 | 34 | //! |
|
46 | 46 | //! * You want a heap-allocated array. |
47 | 47 | //! |
48 | 48 | //! ### Use a `VecDeque` when: |
49 | | -//! * You want a `Vec` that supports efficient insertion at both ends of the |
| 49 | +//! * You want a [`Vec`] that supports efficient insertion at both ends of the |
50 | 50 | //! sequence. |
51 | 51 | //! * You want a queue. |
52 | 52 | //! * You want a double-ended queue (deque). |
53 | 53 | //! |
54 | 54 | //! ### Use a `LinkedList` when: |
55 | | -//! * You want a `Vec` or `VecDeque` of unknown size, and can't tolerate |
| 55 | +//! * You want a [`Vec`] or [`VecDeque`] of unknown size, and can't tolerate |
56 | 56 | //! amortization. |
57 | 57 | //! * You want to efficiently split and append lists. |
58 | 58 | //! * You are *absolutely* certain you *really*, *truly*, want a doubly linked |
|
92 | 92 | //! Throughout the documentation, we will follow a few conventions. For all |
93 | 93 | //! operations, the collection's size is denoted by n. If another collection is |
94 | 94 | //! involved in the operation, it contains m elements. Operations which have an |
95 | | -//! *amortized* cost are suffixed with a `*`. Operations with an *expected* |
| 95 | +//! *amortized* cost are suffixed with a `*`. Operations with an *expected* |
96 | 96 | //! cost are suffixed with a `~`. |
97 | 97 | //! |
98 | 98 | //! All amortized costs are for the potential need to resize when capacity is |
99 | | -//! exhausted. If a resize occurs it will take O(n) time. Our collections never |
| 99 | +//! exhausted. If a resize occurs it will take O(n) time. Our collections never |
100 | 100 | //! automatically shrink, so removal operations aren't amortized. Over a |
101 | 101 | //! sufficiently large series of operations, the average cost per operation will |
102 | 102 | //! deterministically equal the given cost. |
103 | 103 | //! |
104 | | -//! Only HashMap has expected costs, due to the probabilistic nature of hashing. |
105 | | -//! It is theoretically possible, though very unlikely, for HashMap to |
| 104 | +//! Only [`HashMap`] has expected costs, due to the probabilistic nature of hashing. |
| 105 | +//! It is theoretically possible, though very unlikely, for [`HashMap`] to |
106 | 106 | //! experience worse performance. |
107 | 107 | //! |
108 | 108 | //! ## Sequences |
109 | 109 | //! |
110 | | -//! | | get(i) | insert(i) | remove(i) | append | split_off(i) | |
111 | | -//! |--------------|----------------|-----------------|----------------|--------|----------------| |
112 | | -//! | Vec | O(1) | O(n-i)* | O(n-i) | O(m)* | O(n-i) | |
113 | | -//! | VecDeque | O(1) | O(min(i, n-i))* | O(min(i, n-i)) | O(m)* | O(min(i, n-i)) | |
114 | | -//! | LinkedList | O(min(i, n-i)) | O(min(i, n-i)) | O(min(i, n-i)) | O(1) | O(min(i, n-i)) | |
| 110 | +//! | | get(i) | insert(i) | remove(i) | append | split_off(i) | |
| 111 | +//! |----------------|----------------|-----------------|----------------|--------|----------------| |
| 112 | +//! | [`Vec`] | O(1) | O(n-i)* | O(n-i) | O(m)* | O(n-i) | |
| 113 | +//! | [`VecDeque`] | O(1) | O(min(i, n-i))* | O(min(i, n-i)) | O(m)* | O(min(i, n-i)) | |
| 114 | +//! | [`LinkedList`] | O(min(i, n-i)) | O(min(i, n-i)) | O(min(i, n-i)) | O(1) | O(min(i, n-i)) | |
115 | 115 | //! |
116 | | -//! Note that where ties occur, Vec is generally going to be faster than VecDeque, and VecDeque |
117 | | -//! is generally going to be faster than LinkedList. |
| 116 | +//! Note that where ties occur, [`Vec`] is generally going to be faster than [`VecDeque`], and |
| 117 | +//! [`VecDeque`] is generally going to be faster than [`LinkedList`]. |
118 | 118 | //! |
119 | 119 | //! ## Maps |
120 | 120 | //! |
121 | 121 | //! For Sets, all operations have the cost of the equivalent Map operation. |
122 | 122 | //! |
123 | | -//! | | get | insert | remove | predecessor | append | |
124 | | -//! |----------|-----------|----------|----------|-------------|--------| |
125 | | -//! | HashMap | O(1)~ | O(1)~* | O(1)~ | N/A | N/A | |
126 | | -//! | BTreeMap | O(log n) | O(log n) | O(log n) | O(log n) | O(n+m) | |
| 123 | +//! | | get | insert | remove | predecessor | append | |
| 124 | +//! |--------------|-----------|----------|----------|-------------|--------| |
| 125 | +//! | [`HashMap`] | O(1)~ | O(1)~* | O(1)~ | N/A | N/A | |
| 126 | +//! | [`BTreeMap`] | O(log n) | O(log n) | O(log n) | O(log n) | O(n+m) | |
127 | 127 | //! |
128 | 128 | //! # Correct and Efficient Usage of Collections |
129 | 129 | //! |
|
136 | 136 | //! ## Capacity Management |
137 | 137 | //! |
138 | 138 | //! Many collections provide several constructors and methods that refer to |
139 | | -//! "capacity". These collections are generally built on top of an array. |
| 139 | +//! "capacity". These collections are generally built on top of an array. |
140 | 140 | //! Optimally, this array would be exactly the right size to fit only the |
141 | 141 | //! elements stored in the collection, but for the collection to do this would |
142 | 142 | //! be very inefficient. If the backing array was exactly the right size at all |
|
157 | 157 | //! information to do this itself. Therefore, it is up to us programmers to give |
158 | 158 | //! it hints. |
159 | 159 | //! |
160 | | -//! Any `with_capacity` constructor will instruct the collection to allocate |
| 160 | +//! Any `with_capacity()` constructor will instruct the collection to allocate |
161 | 161 | //! enough space for the specified number of elements. Ideally this will be for |
162 | 162 | //! exactly that many elements, but some implementation details may prevent |
163 | | -//! this. `Vec` and `VecDeque` can be relied on to allocate exactly the |
164 | | -//! requested amount, though. Use `with_capacity` when you know exactly how many |
| 163 | +//! this. [`Vec`] and [`VecDeque`] can be relied on to allocate exactly the |
| 164 | +//! requested amount, though. Use `with_capacity()` when you know exactly how many |
165 | 165 | //! elements will be inserted, or at least have a reasonable upper-bound on that |
166 | 166 | //! number. |
167 | 167 | //! |
168 | | -//! When anticipating a large influx of elements, the `reserve` family of |
| 168 | +//! When anticipating a large influx of elements, the `reserve()` family of |
169 | 169 | //! methods can be used to hint to the collection how much room it should make |
170 | | -//! for the coming items. As with `with_capacity`, the precise behavior of |
| 170 | +//! for the coming items. As with `with_capacity()`, the precise behavior of |
171 | 171 | //! these methods will be specific to the collection of interest. |
172 | 172 | //! |
173 | 173 | //! For optimal performance, collections will generally avoid shrinking |
174 | | -//! themselves. If you believe that a collection will not soon contain any more |
175 | | -//! elements, or just really need the memory, the `shrink_to_fit` method prompts |
| 174 | +//! themselves. If you believe that a collection will not soon contain any more |
| 175 | +//! elements, or just really need the memory, the `shrink_to_fit()` method prompts |
176 | 176 | //! the collection to shrink the backing array to the minimum size capable of |
177 | 177 | //! holding its elements. |
178 | 178 | //! |
179 | 179 | //! Finally, if ever you're interested in what the actual capacity of the |
180 | | -//! collection is, most collections provide a `capacity` method to query this |
181 | | -//! information on demand. This can be useful for debugging purposes, or for |
182 | | -//! use with the `reserve` methods. |
| 180 | +//! collection is, most collections provide a `capacity()` method to query this |
| 181 | +//! information on demand. This can be useful for debugging purposes, or for |
| 182 | +//! use with the `reserve()` methods. |
183 | 183 | //! |
184 | 184 | //! ## Iterators |
185 | 185 | //! |
|
194 | 194 | //! |
195 | 195 | //! All of the standard collections provide several iterators for performing |
196 | 196 | //! bulk manipulation of their contents. The three primary iterators almost |
197 | | -//! every collection should provide are `iter`, `iter_mut`, and `into_iter`. |
| 197 | +//! every collection should provide are `iter()`, `iter_mut()`, and `into_iter()`. |
198 | 198 | //! Some of these are not provided on collections where it would be unsound or |
199 | 199 | //! unreasonable to provide them. |
200 | 200 | //! |
201 | | -//! `iter` provides an iterator of immutable references to all the contents of a |
202 | | -//! collection in the most "natural" order. For sequence collections like `Vec`, |
| 201 | +//! `iter()` provides an iterator of immutable references to all the contents of a |
| 202 | +//! collection in the most "natural" order. For sequence collections like [`Vec`], |
203 | 203 | //! this means the items will be yielded in increasing order of index starting |
204 | | -//! at 0. For ordered collections like `BTreeMap`, this means that the items |
205 | | -//! will be yielded in sorted order. For unordered collections like `HashMap`, |
| 204 | +//! at 0. For ordered collections like [`BTreeMap`], this means that the items |
| 205 | +//! will be yielded in sorted order. For unordered collections like [`HashMap`], |
206 | 206 | //! the items will be yielded in whatever order the internal representation made |
207 | 207 | //! most convenient. This is great for reading through all the contents of the |
208 | 208 | //! collection. |
|
214 | 214 | //! } |
215 | 215 | //! ``` |
216 | 216 | //! |
217 | | -//! `iter_mut` provides an iterator of *mutable* references in the same order as |
218 | | -//! `iter`. This is great for mutating all the contents of the collection. |
| 217 | +//! `iter_mut()` provides an iterator of *mutable* references in the same order as |
| 218 | +//! `iter()`. This is great for mutating all the contents of the collection. |
219 | 219 | //! |
220 | 220 | //! ``` |
221 | 221 | //! let mut vec = vec![1, 2, 3, 4]; |
|
224 | 224 | //! } |
225 | 225 | //! ``` |
226 | 226 | //! |
227 | | -//! `into_iter` transforms the actual collection into an iterator over its |
| 227 | +//! `into_iter()` transforms the actual collection into an iterator over its |
228 | 228 | //! contents by-value. This is great when the collection itself is no longer |
229 | | -//! needed, and the values are needed elsewhere. Using `extend` with `into_iter` |
| 229 | +//! needed, and the values are needed elsewhere. Using `extend()` with `into_iter()` |
230 | 230 | //! is the main way that contents of one collection are moved into another. |
231 | | -//! `extend` automatically calls `into_iter`, and takes any `T: IntoIterator`. |
232 | | -//! Calling `collect` on an iterator itself is also a great way to convert one |
| 231 | +//! `extend()` automatically calls `into_iter()`, and takes any `T: `[`IntoIterator`]. |
| 232 | +//! Calling `collect()` on an iterator itself is also a great way to convert one |
233 | 233 | //! collection into another. Both of these methods should internally use the |
234 | 234 | //! capacity management tools discussed in the previous section to do this as |
235 | 235 | //! efficiently as possible. |
|
248 | 248 | //! ``` |
249 | 249 | //! |
250 | 250 | //! Iterators also provide a series of *adapter* methods for performing common |
251 | | -//! threads to sequences. Among the adapters are functional favorites like `map`, |
252 | | -//! `fold`, `skip`, and `take`. Of particular interest to collections is the |
253 | | -//! `rev` adapter, that reverses any iterator that supports this operation. Most |
| 251 | +//! threads to sequences. Among the adapters are functional favorites like `map()`, |
| 252 | +//! `fold()`, `skip()` and `take()`. Of particular interest to collections is the |
| 253 | +//! `rev()` adapter, that reverses any iterator that supports this operation. Most |
254 | 254 | //! collections provide reversible iterators as the way to iterate over them in |
255 | 255 | //! reverse order. |
256 | 256 | //! |
|
263 | 263 | //! |
264 | 264 | //! Several other collection methods also return iterators to yield a sequence |
265 | 265 | //! of results but avoid allocating an entire collection to store the result in. |
266 | | -//! This provides maximum flexibility as `collect` or `extend` can be called to |
| 266 | +//! This provides maximum flexibility as `collect()` or `extend()` can be called to |
267 | 267 | //! "pipe" the sequence into any collection if desired. Otherwise, the sequence |
268 | 268 | //! can be looped over with a `for` loop. The iterator can also be discarded |
269 | 269 | //! after partial use, preventing the computation of the unused items. |
270 | 270 | //! |
271 | 271 | //! ## Entries |
272 | 272 | //! |
273 | | -//! The `entry` API is intended to provide an efficient mechanism for |
| 273 | +//! The `entry()` API is intended to provide an efficient mechanism for |
274 | 274 | //! manipulating the contents of a map conditionally on the presence of a key or |
275 | 275 | //! not. The primary motivating use case for this is to provide efficient |
276 | 276 | //! accumulator maps. For instance, if one wishes to maintain a count of the |
277 | 277 | //! number of times each key has been seen, they will have to perform some |
278 | 278 | //! conditional logic on whether this is the first time the key has been seen or |
279 | | -//! not. Normally, this would require a `find` followed by an `insert`, |
| 279 | +//! not. Normally, this would require a `find()` followed by an `insert()`, |
280 | 280 | //! effectively duplicating the search effort on each insertion. |
281 | 281 | //! |
282 | 282 | //! When a user calls `map.entry(&key)`, the map will search for the key and |
283 | 283 | //! then yield a variant of the `Entry` enum. |
284 | 284 | //! |
285 | 285 | //! If a `Vacant(entry)` is yielded, then the key *was not* found. In this case |
286 | | -//! the only valid operation is to `insert` a value into the entry. When this is |
| 286 | +//! the only valid operation is to `insert()` a value into the entry. When this is |
287 | 287 | //! done, the vacant entry is consumed and converted into a mutable reference to |
288 | 288 | //! the value that was inserted. This allows for further manipulation of the |
289 | 289 | //! value beyond the lifetime of the search itself. This is useful if complex |
290 | 290 | //! logic needs to be performed on the value regardless of whether the value was |
291 | 291 | //! just inserted. |
292 | 292 | //! |
293 | 293 | //! If an `Occupied(entry)` is yielded, then the key *was* found. In this case, |
294 | | -//! the user has several options: they can `get`, `insert`, or `remove` the |
| 294 | +//! the user has several options: they can `get()`, `insert()` or `remove()` the |
295 | 295 | //! value of the occupied entry. Additionally, they can convert the occupied |
296 | 296 | //! entry into a mutable reference to its value, providing symmetry to the |
297 | | -//! vacant `insert` case. |
| 297 | +//! vacant `insert()` case. |
298 | 298 | //! |
299 | 299 | //! ### Examples |
300 | 300 | //! |
301 | | -//! Here are the two primary ways in which `entry` is used. First, a simple |
| 301 | +//! Here are the two primary ways in which `entry()` is used. First, a simple |
302 | 302 | //! example where the logic performed on the values is trivial. |
303 | 303 | //! |
304 | 304 | //! #### Counting the number of times each character in a string occurs |
|
322 | 322 | //! ``` |
323 | 323 | //! |
324 | 324 | //! When the logic to be performed on the value is more complex, we may simply |
325 | | -//! use the `entry` API to ensure that the value is initialized, and perform the |
| 325 | +//! use the `entry()` API to ensure that the value is initialized and perform the |
326 | 326 | //! logic afterwards. |
327 | 327 | //! |
328 | 328 | //! #### Tracking the inebriation of customers at a bar |
|
406 | 406 | //! // ...but the key hasn't changed. b is still "baz", not "xyz". |
407 | 407 | //! assert_eq!(map.keys().next().unwrap().b, "baz"); |
408 | 408 | //! ``` |
| 409 | +//! |
| 410 | +//! [`Vec`]: ../../std/vec/struct.Vec.html |
| 411 | +//! [`HashMap`]: ../../std/collections/struct.HashMap.html |
| 412 | +//! [`VecDeque`]: ../../std/collections/struct.VecDeque.html |
| 413 | +//! [`LinkedList`]: ../../std/collections/struct.LinkedList.html |
| 414 | +//! [`BTreeMap`]: ../../std/collections/struct.BTreeMap.html |
| 415 | +//! [`HashSet`]: ../../std/collections/struct.HashSet.html |
| 416 | +//! [`BTreeSet`]: ../../std/collections/struct.BTreeSet.html |
| 417 | +//! [`BinaryHeap`]: ../../std/collections/struct.BinaryHeap.html |
| 418 | +//! [`IntoIterator`]: ../../std/iter/trait.IntoIterator.html |
409 | 419 |
|
410 | 420 | #![stable(feature = "rust1", since = "1.0.0")] |
411 | 421 |
|
|
0 commit comments