Rust's standard collection library provides efficient implementations of the most common general-purpose programming data structures. This chapter discusses the implementation of the commonly used collections − Vector, HashMap and HashSet.
A Vector is a resizable array. It stores values in contiguous memory blocks. The predefined structure Vec can be used to create vectors. Some important features of a Vector are −
A Vector can grow or shrink at runtime.
A Vector is a homogeneous collection.
A Vector stores data as sequence of elements in a particular order. Every element in a Vector is assigned a unique index number. The index starts from 0 and goes up to n-1 where, n is the size of the collection. For example, in a collection of 5 elements, the first element will be at index 0 and the last element will be at index 4.
A Vector will only append values to (or near) the end. In other words, a Vector can be used to implement a stack.
Memory for a Vector is allocated in the heap.
let mut instance_name = Vec::new();
The static method new() of the Vecstructure is used to create a vector instance.
Alternatively, a vector can also be created using the vec! macro. The syntax is as given below −
let vector_name = vec![val1,val2,val3]
The following table lists some commonly used functions of the Vec structure.
Sr.No | Method | Signature & Description |
---|---|---|
1 | new() | pub fn new()->Vect Constructs a new, empty Vec. The vector will not allocate until elements are pushed onto it. |
2 | push() | pub fn push(&mut self, value: T) Appends an element to the back of a collection. |
3 | remove() | pub fn remove(&mut self, index: usize) -> T Removes and returns the element at position index within the vector, shifting all elements after it to the left. |
4 | contains() | pub fn contains(&self, x: &T) -> bool Returns true if the slice contains an element with the given value. |
5 | len() | pub fn len(&self) -> usize Returns the number of elements in the vector, also referred to as its 'length'. |
To create a vector, we use the static method new−
fn main() { let mut v = Vec::new(); v.push(20); v.push(30); v.push(40); println!("size of vector is :{}",v.len()); println!("{:?}",v); }
The above example creates a Vector using the static method new() that is defined in structure Vec. The push(val) function appends the value passed as parameter to the collection. The len() function returns the length of the vector.
size of vector is :3 [20, 30, 40]
The following code creates a vector using the vec! macro. The data type of the vector is inferred the first value that is assigned to it.
fn main() { let v = vec![1,2,3]; println!("{:?}",v); }
[1, 2, 3]
As mentioned earlier, a vector can only contain values of the same data type. The following snippet will throw a error[E0308]: mismatched types error.
fn main() { let v = vec![1,2,3,"hello"]; println!("{:?}",v); }
Appends an element to the end of a collection.
fn main() { let mut v = Vec::new(); v.push(20); v.push(30); v.push(40); println!("{:?}",v); }
[20, 30, 40]
Removes and returns the element at position index within the vector, shifting all elements after it to the left.
fn main() { let mut v = vec![10,20,30]; v.remove(1); println!("{:?}",v); }
[10, 30]
Returns true if the slice contains an element with the given value −
fn main() { let v = vec![10,20,30]; if v.contains(&10) { println!("found 10"); } println!("{:?}",v); }
found 10 [10, 20, 30]
Returns the number of elements in the vector, also referred to as its 'length'.
fn main() { let v = vec![1,2,3]; println!("size of vector is :{}",v.len()); }
size of vector is :3
Individual elements in a vector can be accessed using their corresponding index numbers. The following example creates a vector ad prints the value of the first element.
fn main() { let mut v = Vec::new(); v.push(20); v.push(30); println!("{:?}",v[0]); } Output: `20`
Values in a vector can also be fetched using reference to the collection.
fn main() { let mut v = Vec::new(); v.push(20); v.push(30); v.push(40); v.push(500); for i in &v { println!("{}",i); } println!("{:?}",v); }
20 30 40 500 [20, 30, 40, 500]
A map is a collection of key-value pairs (called entries). No two entries in a map can have the same key. In short, a map is a lookup table. A HashMap stores the keys and values in a hash table. The entries are stored in an arbitrary order. The key is used to search for values in the HashMap. The HashMap structure is defined in the std::collections module. This module should be explicitly imported to access the HashMap structure.
let mut instance_name = HashMap::new();
The static method new() of the HashMap structure is used to create a HashMap object. This method creates an empty HashMap.
The commonly used functions of HashMap are discussed below −
Sr.No | Method | Signature & Description |
---|---|---|
1 | insert() | pub fn insert(&mut self, k: K, v: V) -> Option Inserts a key/value pair, if no key then None is returned. After update, old value is returned. |
2 | len() | pub fn len(&self) -> usize Returns the number of elements in the map. |
3 | get() | pub fn get<Q: ?Sized>(&lself, k: &Q) -> Option<&V> where K:Borrow Q:Hash+ Eq Returns a reference to the value corresponding to the key. |
4 | iter() | pub fn iter(&self) -> Iter<K, V> An iterator visiting all key-value pairs in arbitrary order. The iterator element type is (&'a K, &'a V). |
5 | contains_key | pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool Returns true if the map contains a value for the specified key. |
6 | remove() | pub fn remove_entry<Q: ?Sized>(&mut self, k: &Q) -> Option<(K, V)> Removes a key from the map, returning the stored key and value if the key was previously in the map. |
Inserts a key/value pair into the HashMap.
use std::collections::HashMap; fn main(){ let mut stateCodes = HashMap::new(); stateCodes.insert("KL","Kerala"); stateCodes.insert("MH","Maharashtra"); println!("{:?}",stateCodes); }
The above program creates a HashMap and initializes it with 2 key-value pairs.
{"KL": "Kerala", "MH": "Maharashtra"}
Returns the number of elements in the map
use std::collections::HashMap; fn main() { let mut stateCodes = HashMap::new(); stateCodes.insert("KL","Kerala"); stateCodes.insert("MH","Maharashtra"); println!("size of map is {}",stateCodes.len()); }
The above example creates a HashMap and prints the total number of elements in it.
size of map is 2
Returns a reference to the value corresponding to the key. The following example retrieves the value for key KL in the HashMap.
use std::collections::HashMap; fn main() { let mut stateCodes = HashMap::new(); stateCodes.insert("KL","Kerala"); stateCodes.insert("MH","Maharashtra"); println!("size of map is {}",stateCodes.len()); println!("{:?}",stateCodes); match stateCodes.get(&"KL") { Some(value)=> { println!("Value for key KL is {}",value); } None => { println!("nothing found"); } } }
size of map is 2 {"KL": "Kerala", "MH": "Maharashtra"} Value for key KL is Kerala
Returns an iterator containing reference to all key-value pairs in an arbitrary order.
use std::collections::HashMap; fn main() { let mut stateCodes = HashMap::new(); stateCodes.insert("KL","Kerala"); stateCodes.insert("MH","Maharashtra"); for (key, val) in stateCodes.iter() { println!("key: {} val: {}", key, val); } }
key: MH val: Maharashtra key: KL val: Kerala
Returns true if the map contains a value for the specified key.
use std::collections::HashMap; fn main() { let mut stateCodes = HashMap::new(); stateCodes.insert("KL","Kerala"); stateCodes.insert("MH","Maharashtra"); stateCodes.insert("GJ","Gujarat"); if stateCodes.contains_key(&"GJ") { println!("found key"); } }
found key
Removes a key from the map.
use std::collections::HashMap; fn main() { let mut stateCodes = HashMap::new(); stateCodes.insert("KL","Kerala"); stateCodes.insert("MH","Maharashtra"); stateCodes.insert("GJ","Gujarat"); println!("length of the hashmap {}",stateCodes.len()); stateCodes.remove(&"GJ"); println!("length of the hashmap after remove() {}",stateCodes.len()); }
length of the hashmap 3 length of the hashmap after remove() 2
HashSet is a set of unique values of type T. Adding and removing values is fast, and it is fast to ask whether a given value is in the set or not. The HashSet structure is defined in the std::collections module. This module should be explicitly imported to access the HashSet structure.
let mut hash_set_name = HashSet::new();
The static method, new, of HashSet structure is used to create a HashSet. This method creates an empty HashSet.
The following table lists some of the commonly used methods of the HashSet structure.
Sr.No | Method | Signature & Description |
---|---|---|
1 | insert() | pub fn insert(&mut self, value: T) -> bool Adds a value to the set. If the set did not have this value present, true is returned else false. |
2 | len() | pub fn len(&self) -> usize Returns the number of elements in the set. |
3 | get() | pub fn get<Q:?Sized>(&self, value: &Q) -> Option<&T> where T: Borrow,Q: Hash + Eq, Returns a reference to the value in the set, if any that is equal to the given value. |
4 | iter() | pub fn iter(&self) -> Iter Returns an iterator visiting all elements in arbitrary order. The iterator element type is &'a T. |
5 | contains_key | pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool Returns true if the set contains a value. |
6 | remove() | pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool Removes a value from the set. Returns true if the value was present in the set. |
Adds a value to the set. A HashSet does not add duplicate values to the collection.
use std::collections::HashSet; fn main() { let mut names = HashSet::new(); names.insert("Mohtashim"); names.insert("Kannan"); names.insert("Howcodex"); names.insert("Mohtashim");//duplicates not added println!("{:?}",names); }
{"Howcodex", "Kannan", "Mohtashim"}
Returns the number of elements in the set.
use std::collections::HashSet; fn main() { let mut names = HashSet::new(); names.insert("Mohtashim"); names.insert("Kannan"); names.insert("Howcodex"); println!("size of the set is {}",names.len()); }
size of the set is 3
Retruns an iterator visiting all elements in arbitrary order.
use std::collections::HashSet; fn main() { let mut names = HashSet::new(); names.insert("Mohtashim"); names.insert("Kannan"); names.insert("Howcodex"); names.insert("Mohtashim"); for name in names.iter() { println!("{}",name); } }
Howcodex Mohtashim Kannan
Returns a reference to the value in the set, if any, which is equal to the given value.
use std::collections::HashSet; fn main() { let mut names = HashSet::new(); names.insert("Mohtashim"); names.insert("Kannan"); names.insert("Howcodex"); names.insert("Mohtashim"); match names.get(&"Mohtashim"){ Some(value)=>{ println!("found {}",value); } None =>{ println!("not found"); } } println!("{:?}",names); }
found Mohtashim {"Kannan", "Mohtashim", "Howcodex"}
Returns true if the set contains a value.
use std::collections::HashSet; fn main() { let mut names = HashSet::new(); names.insert("Mohtashim"); names.insert("Kannan"); names.insert("Howcodex"); if names.contains(&"Kannan") { println!("found name"); } }
found name
Removes a value from the set.
use std::collections::HashSet; fn main() { let mut names = HashSet::new(); names.insert("Mohtashim"); names.insert("Kannan"); names.insert("Howcodex"); println!("length of the Hashset: {}",names.len()); names.remove(&"Kannan"); println!("length of the Hashset after remove() : {}",names.len()); }
length of the Hashset: 3 length of the Hashset after remove() : 2