|
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