Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Things on this page are fragmentary and immature notes/thoughts of the author. Please read with your own judgement!

:timing
:sccache 1

Tips and Traps

  1. Summary of Collections in Rust has a good summary on when to each which collection in Rust.

  2. Struct std::collections::HashSet has a good discussion on implementation details on HashSet and things to note when use it.

  3. BTreeSet is an alternative B-Tree-based implementation to HashSet. Elements in BTreeSet are sorted while elements in a HashSet are not sorted.

  4. TinySet provides a few collections that are optimized to scale in size well for small numbers of elements, while still scaling well in time (and size) for numbers of elements.

use std::collections::HashSet;

capacity

Creates an empty HashSet with the specified capacity. The hash set will be able to hold at least capacity elements without reallocating. If capacity is 0, the hash set will not allocate.

{
    let s: HashSet<i32> = [0, 1, 2, 3, 4].iter().cloned().collect();
    s.capacity()
}
7
{
    let s: HashSet<i32> = HashSet::with_capacity(20);
    s.capacity()
}
28

clear

{
    let mut s: HashSet<i32> = [0, 1, 2, 3, 4].iter().cloned().collect();
    s.clear();
    s
}
{}

contains

{
    let mut s: HashSet<i32> = [0, 1, 2, 3, 4].iter().cloned().collect();
    s.contains(&1)
}
true
{
    let mut s: HashSet<i32> = [0, 1, 2, 3, 4].iter().cloned().collect();
    s.contains(&10)
}
false

difference

{
    let s1: HashSet<i32> = [0, 1, 2, 3, 4].iter().cloned().collect();
    let s2: HashSet<i32> = [3, 4].iter().cloned().collect();
    println!("s1 - s2: {:?}", &s1 - &s2);
    println!("s1: {:?}", s1);
}
s1 - s2: {1, 0, 2}
s1: {0, 2, 3, 1, 4}
()
{
    let s1: HashSet<i32> = [0, 1, 2, 3, 4].iter().cloned().collect();
    let s2: HashSet<i32> = [3, 4].iter().cloned().collect();
    println!("s1.difference(s2): {:?}", s1.difference(&s2));
    println!("s1: {:?}", s1);
}
s1.difference(s2): [0, 2, 1]
s1: {0, 2, 3, 4, 1}
()

get

let s: HashSet<i32> = [0, 1, 2, 3, 4].iter().cloned().collect();
s.get(&1)
Some(1)
let s: HashSet<i32> = [0, 1, 2, 3, 4].iter().cloned().collect();
s.get(&10)
None

get_or_insert

#![feature(hash_set_entry)]
{
    let s: HashSet<i32> = [0, 1, 2, 3, 4].iter().cloned().collect();
    let v = s.get_or_insert(5);
    println!("v: {}", v);
    println!("{:?}", s);
}
    let v = s.get_or_insert(5);
              ^^^^^^^^^^^^^ 
use of unstable library feature 'hash_set_entry'

insert

{
    let mut s: HashSet<i32> = [0, 1, 2, 3, 4].iter().cloned().collect();
    s.insert(100);
    s
}
{4, 100, 0, 1, 2, 3}

intersection

let s1: HashSet<i32> = [0, 1, 2, 3, 4].iter().cloned().collect();
let s2: HashSet<i32> = [3, 4, 5, 6, 7].iter().cloned().collect();
s1.intersection(&s2)
[3, 4]

is_disjoin

let s1: HashSet<i32> = [0, 1, 2, 3, 4].iter().cloned().collect();
let s2: HashSet<i32> = [3, 4, 5, 6, 7].iter().cloned().collect();
s1.is_disjoint(&s2)
false
let s1: HashSet<i32> = [0, 1, 2, 3].iter().cloned().collect();
let s2: HashSet<i32> = [4, 5, 6, 7].iter().cloned().collect();
s1.is_disjoint(&s2)
true

replace

This is the same as the function get_or_insert.

{
    let mut s: HashSet<i32> = [0, 1, 2, 3, 4].iter().cloned().collect();
    s.replace(1);
    s
}
{2, 4, 0, 3, 1}
{
    let mut s: HashSet<i32> = [0, 1, 2, 3, 4].iter().cloned().collect();
    s.replace(100);
    s
}
{2, 3, 0, 100, 4, 1}

BTreeSet as An Alternative to HashSet

BTreeSet is implemented based on B-Tree (binary search tree with each node containing a continuous array to improve caching performance). The main feature of BTreeSet compared to HashSet is that elements in a BTreeSet are sorted!

use std::collections::BTreeSet;
let s: BTreeSet<i32> = [0, 1, 2, 3, 4, 2, 3, 4, 3, 4, 4].iter().cloned().collect();
s
{0, 1, 2, 3, 4}
let s = BTreeSet::from([0, 1, 2, 3, 4, 2, 3, 4, 3, 4, 4]);
s
{0, 1, 2, 3, 4}