Closer Scrutiny of Rust Collections

Reading Time: 3 minutes

The Collections are the general-purpose programming data structures provided by Rust’s Standard library. In Rust, the collections can make possible for two libraries to communicate without significant data conversion. Rust can provide many cool implementations of data structures like Vector, Linked list, Hash map, etc.

Rust Collections can save the data into the Heap, collections decide the size on run-time instead of compile time. This means the amount of data does not need to be known at compile-time and can grow or shrink as the program runs.
Each collection has its specific capabilities and use-cases, we want to choose the appropriate one according to our need for the program. You possibly use Vector or Hashmap in your programs for generic data storage and processing because they are exceptionally good in storing and processing of data.

We have categorised the Rust collections into three groups:

Sequences:

  • Vec
  • LinkedList

Map:

  • HashMap
  • BTreeMap

Sets:

  • HashSet.
  • BTreeSet.

In this blog, we will discuss the different collections that belong to group Sequences. And Rest two groups Map, and Sets we will discuss in the next blog.

Vec:

The Vec is the collection that can store values in sequential blocks of memory. It can work as a resizable array.

  • Vector can grow or shrink at runtime.
  • Vector is a homogeneous collection.
  • It can be used when you want a sequence of elements in a particular order, and will only be appended to (or near) the end.
  • It can also work as a Stack.
  • We can do many operations on Vector like push, remove, length of vector, etc.

Let’s understand more with the help of an example:

fn main() {
    // Initialise the Vector.
   let mut vector_of_numbers = Vec::new();
   
   // Add some values to the Vector.
   vector_of_numbers.push(10);
   vector_of_numbers.push(20);
   vector_of_numbers.push(30);
   
   // Print the size of Vector.
   println!("Size of vector: {}", vector_of_numbers.len());
   
   // Contains operation.
      if vector_of_numbers.contains(&10){
          println!("Yes");
      }
      
   // Print the value from the Vector.
   print!("Values in Vector: ");
   for numbers in &vector_of_numbers {
      print!("{} ", numbers);
     
   }
   
   // Remove a value.
   vector_of_numbers.remove(0);
   println!("\nSize of vector: {}", vector_of_numbers.len());
}

Output:

This image has an empty alt attribute; its file name is screenshot-from-2019-11-04-19-57-02.png

In this example, we have initialised the vector and add some values to the vector. Then check whether the given value is in the vector or not, after that print all the values from the vector.
At last, we have deleted an element of the specific index from the vector by using the remove method.

LinkedList:

The LinkedList allows pushing and popping elements at either end. In Rust, LinkedList is generally used as a double-ended queue. LinkedList is the defacto heroes of the dark world of lock-free concurrency.
Almost always better to use Vec or VecDeque instead of LinkedList. Because the array-based containers are faster, more memory efficient and make better use of CPU cache.


When we can use LinkedList?

  • There is a need of unknown size of Vec.
  • To implement the doubly Linked List.
  • To efficiently split and append lists.

We can perform many operations like push, pop, append, len, clear, contains and many more.
Let’s understand more with the help of an example:

use std::collections::LinkedList;

fn main(){
    // Initialise the linkedlist.
    let mut linked_list: LinkedList<u32> = LinkedList::new();
    
    // Push the element in the linkedlist from front.
    linked_list.push_front(1);
    
    // Push the element in the linkedlist from back.
    linked_list.push_back(2);
    linked_list.push_back(3);
    
    // Change the value by iterating the linkedlist.
    for element in linked_list.iter_mut() {
        *element = *element + 10;
    }

    // Pop the value form the front and back.
    println!("{:?}", linked_list.pop_front());
    print!("{:?}", linked_list.pop_back());
}

Output:

This image has an empty alt attribute; its file name is screenshot-from-2019-10-30-11-51-25.png

In this example, we have initialised the LinkedList and perform operations on that Linked List like push the value, change the value of LinkedList by iterating the LinkedList and pop the element from the LinkedList.

Performance:

Here is the performance comparison chart of different operations on the Collections which comes under Sequences.

This image has an empty alt attribute; its file name is screenshot-from-2019-10-30-12-13-15.png

Note: This is the first part of the series of blogs on Collections, I’ll post next blog soon. Stay Tuned.

Thanks for Reading the blog!

This image has an empty alt attribute; its file name is footer-2.jpg

Written by 

Pankaj Chaudhary is a Software Consultant at Knoldus LLP. He has 1.5+ years of experience with good knowledge of Rust, Python, Java, and C. Now he is working as Rust developer and also works on machine learning and data analysis because he loves to play with data and extract some useful information from it. His hobbies are bike riding and explore new places.

1 thought on “Closer Scrutiny of Rust Collections4 min read

Comments are closed.

Discover more from Knoldus Blogs

Subscribe now to keep reading and get access to the full archive.

Continue reading