Struct std::collections::hash_map::HashMap

1.0.0 · source ·
pub struct HashMap<K, V, S = RandomState> { /* private fields */ }
Expand description

通过二次探测和 SIMD 查找实现的 哈希表

默认情况下,HashMap 使用选择为提供对 HashDoS 攻击的抵抗力的哈希算法。 该算法是随机播种的,并且做出了合理的努力以从主机提供的高质量,安全的随机性源生成此 seed,而不会阻塞程序。 因此,seed 的随机性取决于创建 seed 时系统随机数发生器的输出质量。 特别地,当系统的熵池异常低时 (例如在系统引导期间) 生成的种子可能具有较低的质量。

当前的默认哈希算法是 SipHash 1-3,尽管它可能会在 future 的任何位置进行更改。 虽然它的性能对于中等大小的键非常有竞争力,但其他哈希算法对于小键 (如整数) 和大键 (如长字符串) 的性能将优于它,尽管这些算法通常不能防止诸如 HashDoS 之类的攻击。

可以使用 defaultwith_hasherwith_capacity_and_hasher 方法在每个 HashMap 的基础上替换哈希算法。 hashing algorithms available on crates.io 有很多替代方案。

尽管通常可以通过使用 #[derive(PartialEq, Eq, Hash)] 来实现,但要求键实现 EqHash traits。 如果您自己实现这些,那么拥有以下属性非常重要:

k1 == k2 -> hash(k1) == hash(k2)

换句话说,如果两个键相等,则它们的哈希值必须相等。

以这样一种方式修改键是一个逻辑错误,即键的哈希 (由 Hash 特征确定) 或其相等性 (由 Eq 特征确定) 在更改时发生变化在 map 上。 通常只有通过 CellRefCell,二进制状态,I/O 或不安全代码才能实现此操作。 此类逻辑错误导致的行为未指定,但会封装到观察到逻辑错误的 HashMap 中,不会导致未定义的行为。 这可能包括 panics、不正确的结果、中止、内存泄漏和未中止。

哈希表实现是 Google SwissTable 的 Rust 端口。 可以在 这里 找到 SwissTable 的原始 C++ 版本,而该 CppCon 讨论 概述了该算法的工作原理。

Examples

use std::collections::HashMap;

// 通过类型推断,我们可以省略显式类型签名 (在本示例中为 `HashMap<String, String>`)。
let mut book_reviews = HashMap::new();

// 复习一些书。
book_reviews.insert(
    "Adventures of Huckleberry Finn".to_string(),
    "My favorite book.".to_string(),
);
book_reviews.insert(
    "Grimms' Fairy Tales".to_string(),
    "Masterpiece.".to_string(),
);
book_reviews.insert(
    "Pride and Prejudice".to_string(),
    "Very enjoyable.".to_string(),
);
book_reviews.insert(
    "The Adventures of Sherlock Holmes".to_string(),
    "Eye lyked it alot.".to_string(),
);

// 检查一个特定的。
// 当集合存储拥有的值 (String) 时,仍可以使用引用 (&str) 来查询它们。
if !book_reviews.contains_key("Les Misérables") {
    println!("We've got {} reviews, but Les Misérables ain't one.",
             book_reviews.len());
}

// 糟糕,此评论有很多拼写错误,让我们删除它。
book_reviews.remove("The Adventures of Sherlock Holmes");

// 查找与某些键关联的值。
let to_find = ["Pride and Prejudice", "Alice's Adventure in Wonderland"];
for &book in &to_find {
    match book_reviews.get(book) {
        Some(review) => println!("{book}: {review}"),
        None => println!("{book} is unreviewed.")
    }
}

// 查找某个键的值 (如果找不到该键,就会出现 panic)。
println!("Review for Jane: {}", book_reviews["Pride and Prejudice"]);

// 遍历所有内容。
for (book, review) in &book_reviews {
    println!("{book}: \"{review}\"");
}
Run

可以从数组初始化具有已知项列表的 HashMap

use std::collections::HashMap;

let solar_distance = HashMap::from([
    ("Mercury", 0.4),
    ("Venus", 0.7),
    ("Earth", 1.0),
    ("Mars", 1.5),
]);
Run

HashMap 实现了一个 Entry API,它允许获取、设置、更新和删除键及其值的复杂方法:

use std::collections::HashMap;

// 通过类型推断,我们可以省略显式类型签名 (在本示例中为 `HashMap<&str, u8>`)。
let mut player_stats = HashMap::new();

fn random_stat_buff() -> u8 {
    // 实际上可以在这里返回一些随机值 - 现在让我们返回一些固定值
    42
}

// 仅在键不存在时才插入
player_stats.entry("health").or_insert(100);

// 仅当一个键不存在时,才使用提供新值的函数插入该键
player_stats.entry("defence").or_insert_with(random_stat_buff);

// 更新键,以防止键可能未被设置
let stat = player_stats.entry("attack").or_insert(100);
*stat += random_stat_buff();

// 使用就地可变的在插入之前修改条目
player_stats.entry("mana").and_modify(|mana| *mana += 200).or_insert(100);
Run

HashMap 与自定义键类型一起使用的最简单方法是派生 EqHash。 我们还必须导出 PartialEq

use std::collections::HashMap;

#[derive(Hash, Eq, PartialEq, Debug)]
struct Viking {
    name: String,
    country: String,
}

impl Viking {
    /// 创建一个新的 Viking。
    fn new(name: &str, country: &str) -> Viking {
        Viking { name: name.to_string(), country: country.to_string() }
    }
}

// 使用 HashMap 存储 Viking 的健康点。
let vikings = HashMap::from([
    (Viking::new("Einar", "Norway"), 25),
    (Viking::new("Olaf", "Denmark"), 24),
    (Viking::new("Harald", "Iceland"), 12),
]);

// 使用派生的实现来打印 Viking 的状态。
for (viking, health) in &vikings {
    println!("{viking:?} has {health} hp");
}
Run

Implementations§

source§

impl<K, V> HashMap<K, V, RandomState>

source

pub fn new() -> HashMap<K, V, RandomState>

创建一个空的 HashMap

哈希 map 最初创建时的容量为 0,因此只有在首次插入时才分配。

Examples
use std::collections::HashMap;
let mut map: HashMap<&str, i32> = HashMap::new();
Run
source

pub fn with_capacity(capacity: usize) -> HashMap<K, V, RandomState>

创建一个至少具有指定容量的空 HashMap

哈希 map 将能够至少保留 capacity 个元素而无需重新分配。 此方法允许分配比 capacity 更多的元素。 如果 capacity 为 0,则不会分配哈希 map。

Examples
use std::collections::HashMap;
let mut map: HashMap<&str, i32> = HashMap::with_capacity(10);
Run
source§

impl<K, V, S> HashMap<K, V, S>

1.7.0 (const: unstable) · source

pub fn with_hasher(hash_builder: S) -> HashMap<K, V, S>

创建一个空的 HashMap,它将使用给定的哈希生成器来哈希键。

创建的 map 具有默认的初始容量。

警告: hash_builder 通常是随机生成的,旨在使 HashMaps 能够抵抗导致许多冲突和非常差的性能的攻击。 使用此函数手动设置它可能会导致 DoS 攻击 vector。

传递的 hash_builder 应该为 HashMap 实现 BuildHasher trait 才有用,有关详细信息,请参见其文档。

Examples
use std::collections::HashMap;
use std::collections::hash_map::RandomState;

let s = RandomState::new();
let mut map = HashMap::with_hasher(s);
map.insert(1, 2);
Run
1.7.0 · source

pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> HashMap<K, V, S>

创建一个至少具有指定容量的空 HashMap,使用 hasher 对键进行哈希处理。

哈希 map 将能够至少保留 capacity 个元素而无需重新分配。此方法允许分配比 capacity 更多的元素。 如果 capacity 为 0,则不会分配哈希 map。

警告: hasher 通常是随机生成的,旨在让 HashMaps 能够抵抗导致许多冲突和性能非常差的攻击。

使用此函数手动设置它可能会导致 DoS 攻击 vector。

传递的 hasher 应该实现 BuildHasher trait 以使 HashMap 有用,有关详细信息,请参见其文档。

Examples
use std::collections::HashMap;
use std::collections::hash_map::RandomState;

let s = RandomState::new();
let mut map = HashMap::with_capacity_and_hasher(10, s);
map.insert(1, 2);
Run
source

pub fn capacity(&self) -> usize

返回 map 无需重新分配即可容纳的元素数。

此数字是一个下限; HashMap<K, V> 可能可以容纳更多,但可以保证至少容纳这么多。

Examples
use std::collections::HashMap;
let map: HashMap<i32, i32> = HashMap::with_capacity(100);
assert!(map.capacity() >= 100);
Run
source

pub fn keys(&self) -> Keys<'_, K, V>

一个迭代器,以任意顺序访问所有键。 迭代器元素类型为 &'a K

Examples
use std::collections::HashMap;

let map = HashMap::from([
    ("a", 1),
    ("b", 2),
    ("c", 3),
]);

for key in map.keys() {
    println!("{key}");
}
Run
Performance

在当前的实现中,迭代键需要 O(capacity) 时间而不是 O(len) 时间,因为它在内部也访问了空的 buckets。

1.54.0 · source

pub fn into_keys(self) -> IntoKeys<K, V>

创建一个消费迭代器,以任意顺序访问所有键。 调用后不能使用 map。 迭代器元素类型为 K

Examples
use std::collections::HashMap;

let map = HashMap::from([
    ("a", 1),
    ("b", 2),
    ("c", 3),
]);

let mut vec: Vec<&str> = map.into_keys().collect();
// `IntoKeys` 迭代器以任意顺序生成键,因此必须对键进行排序以针对排序数组测试它们。
vec.sort_unstable();
assert_eq!(vec, ["a", "b", "c"]);
Run
Performance

在当前的实现中,迭代键需要 O(capacity) 时间而不是 O(len) 时间,因为它在内部也访问了空的 buckets。

source

pub fn values(&self) -> Values<'_, K, V>

一个以任意顺序访问所有值的迭代器。 迭代器元素类型为 &'a V

Examples
use std::collections::HashMap;

let map = HashMap::from([
    ("a", 1),
    ("b", 2),
    ("c", 3),
]);

for val in map.values() {
    println!("{val}");
}
Run
Performance

在当前的实现中,迭代值需要 O(capacity) 时间而不是 O(len) 时间,因为它在内部也访问了空的 buckets。

1.10.0 · source

pub fn values_mut(&mut self) -> ValuesMut<'_, K, V>

一个迭代器,它以任意顺序可变地访问所有值。 迭代器元素类型为 &'a mut V

Examples
use std::collections::HashMap;

let mut map = HashMap::from([
    ("a", 1),
    ("b", 2),
    ("c", 3),
]);

for val in map.values_mut() {
    *val = *val + 10;
}

for val in map.values() {
    println!("{val}");
}
Run
Performance

在当前的实现中,迭代值需要 O(capacity) 时间而不是 O(len) 时间,因为它在内部也访问了空的 buckets。

1.54.0 · source

pub fn into_values(self) -> IntoValues<K, V>

创建一个消费迭代器,以任意顺序访问所有值。 调用后不能使用 map。 迭代器元素类型为 V

Examples
use std::collections::HashMap;

let map = HashMap::from([
    ("a", 1),
    ("b", 2),
    ("c", 3),
]);

let mut vec: Vec<i32> = map.into_values().collect();
// `IntoValues` 迭代器以任意顺序生成值,因此必须对这些值进行排序以针对已排序数组对其进行测试。
vec.sort_unstable();
assert_eq!(vec, [1, 2, 3]);
Run
Performance

在当前的实现中,迭代值需要 O(capacity) 时间而不是 O(len) 时间,因为它在内部也访问了空的 buckets。

source

pub fn iter(&self) -> Iter<'_, K, V>

一个迭代器,以任意顺序访问所有键值对。 迭代器元素类型为 (&'a K, &'a V)

Examples
use std::collections::HashMap;

let map = HashMap::from([
    ("a", 1),
    ("b", 2),
    ("c", 3),
]);

for (key, val) in map.iter() {
    println!("key: {key} val: {val}");
}
Run
Performance

在当前实现中,迭代 map 需要 O(capacity) 时间而不是 O(len) 时间,因为它在内部也访问了空的 buckets。

source

pub fn iter_mut(&mut self) -> IterMut<'_, K, V>

一个迭代器,以任意顺序访问所有键值对,并且对值进行可变引用。 迭代器元素类型为 (&'a K, &'a mut V)

Examples
use std::collections::HashMap;

let mut map = HashMap::from([
    ("a", 1),
    ("b", 2),
    ("c", 3),
]);

// 更新所有值
for (_, val) in map.iter_mut() {
    *val *= 2;
}

for (key, val) in &map {
    println!("key: {key} val: {val}");
}
Run
Performance

在当前实现中,迭代 map 需要 O(capacity) 时间而不是 O(len) 时间,因为它在内部也访问了空的 buckets。

source

pub fn len(&self) -> usize

返回 map 中的元素数。

Examples
use std::collections::HashMap;

let mut a = HashMap::new();
assert_eq!(a.len(), 0);
a.insert(1, "a");
assert_eq!(a.len(), 1);
Run
source

pub fn is_empty(&self) -> bool

如果 map 不包含任何元素,则返回 true

Examples
use std::collections::HashMap;

let mut a = HashMap::new();
assert!(a.is_empty());
a.insert(1, "a");
assert!(!a.is_empty());
Run
1.6.0 · source

pub fn drain(&mut self) -> Drain<'_, K, V>

清除 map,将所有键值对作为迭代器返回。保留分配的内存以供重用。

如果返回的迭代器在被完全消耗之前被丢弃,则丢弃剩余的键值对 返回的迭代器在 map 上保留一个错误借用以优化其实现。

Examples
use std::collections::HashMap;

let mut a = HashMap::new();
a.insert(1, "a");
a.insert(2, "b");

for (k, v) in a.drain().take(1) {
    assert!(k == 1 || k == 2);
    assert!(v == "a" || v == "b");
}

assert!(a.is_empty());
Run
source

pub fn drain_filter<F>(&mut self, pred: F) -> DrainFilter<'_, K, V, F> where F: FnMut(&K, &mut V) -> bool,

🔬This is a nightly-only experimental API. (hash_drain_filter #59618)

创建一个迭代器,该迭代器使用闭包确定是否应删除元素。

如果闭包返回 true,则将元素从 map 中移除并产生。 如果闭包返回 false 或 panics,则该元素保留在 map 中,并且不会产生。

请注意,无论选择保留还是删除 drain_filter,您都可以对过滤器闭包中的每个值进行可变的。

如果迭代器仅被部分消耗或根本没有被消耗,则其余所有元素仍将受到闭包的处理,如果返回 true,则将其删除并丢弃。

如果在闭包中出现 panic,或者在丢弃元素时发生 panic,或者 DrainFilter 值泄漏,将有多少个元素受到该闭包的影响,这是不确定的。

Examples

将 map 分为偶数和奇数键,重新使用原始的 map:

#![feature(hash_drain_filter)]
use std::collections::HashMap;

let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x)).collect();
let drained: HashMap<i32, i32> = map.drain_filter(|k, _v| k % 2 == 0).collect();

let mut evens = drained.keys().copied().collect::<Vec<_>>();
let mut odds = map.keys().copied().collect::<Vec<_>>();
evens.sort();
odds.sort();

assert_eq!(evens, vec![0, 2, 4, 6]);
assert_eq!(odds, vec![1, 3, 5, 7]);
Run
1.18.0 · source

pub fn retain<F>(&mut self, f: F)where F: FnMut(&K, &mut V) -> bool,

仅保留谓词指定的元素。

换句话说,删除所有 f(&k, &mut v) 返回 false(k, v) 对。 元素以未排序 (和未指定) 的顺序访问。

Examples
use std::collections::HashMap;

let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x*10)).collect();
map.retain(|&k, _| k % 2 == 0);
assert_eq!(map.len(), 4);
Run
Performance

在当前的实现中,这个操作需要 O(capacity) 时间而不是 O(len),因为它在内部也访问了空的 buckets。

source

pub fn clear(&mut self)

清除 map,删除所有键值对。 保留分配的内存以供重用。

Examples
use std::collections::HashMap;

let mut a = HashMap::new();
a.insert(1, "a");
a.clear();
assert!(a.is_empty());
Run
1.9.0 · source

pub fn hasher(&self) -> &S

返回 map 的 BuildHasher 的引用。

Examples
use std::collections::HashMap;
use std::collections::hash_map::RandomState;

let hasher = RandomState::new();
let map: HashMap<i32, i32> = HashMap::with_hasher(hasher);
let hasher: &RandomState = map.hasher();
Run
source§

impl<K, V, S> HashMap<K, V, S>where K: Eq + Hash, S: BuildHasher,

source

pub fn reserve(&mut self, additional: usize)

保留至少 additional 个要插入 HashMap 中的更多元素的容量。集合可以保留更多空间来推测性地避免频繁的重新分配。

调用 reserve 后,容量将大于或等于 self.len() + additional。 如果容量已经足够,则不执行任何操作。

Panics

如果新的分配大小溢出 usize,就会出现 panics。

Examples
use std::collections::HashMap;
let mut map: HashMap<&str, i32> = HashMap::new();
map.reserve(10);
Run
1.57.0 · source

pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>

尝试为要插入到 HashMap 中的至少 additional 更多元素保留容量。集合可以保留更多空间来推测性地避免频繁的重新分配。

调用 try_reserve 后,如果返回 Ok(()),容量将大于等于 self.len() + additional。 如果容量已经足够,则不执行任何操作。

Errors

如果容量溢出,或者分配器报告失败,则返回错误。

Examples
use std::collections::HashMap;

let mut map: HashMap<&str, isize> = HashMap::new();
map.try_reserve(10).expect("why is the test harness OOMing on a handful of bytes?");
Run
source

pub fn shrink_to_fit(&mut self)

尽可能缩小 map 的容量。 它会在保持内部规则的同时尽可能地丢弃,并可能根据调整大小策略留出一些空间。

Examples
use std::collections::HashMap;

let mut map: HashMap<i32, i32> = HashMap::with_capacity(100);
map.insert(1, 2);
map.insert(3, 4);
assert!(map.capacity() >= 100);
map.shrink_to_fit();
assert!(map.capacity() >= 2);
Run
1.56.0 · source

pub fn shrink_to(&mut self, min_capacity: usize)

降低 map 的容量。 它将降低不低于提供的限制,同时保持内部规则,并可能根据调整大小策略留下一些空间。

如果当前容量小于下限,则为无操作。

Examples
use std::collections::HashMap;

let mut map: HashMap<i32, i32> = HashMap::with_capacity(100);
map.insert(1, 2);
map.insert(3, 4);
assert!(map.capacity() >= 100);
map.shrink_to(10);
assert!(map.capacity() >= 10);
map.shrink_to(0);
assert!(map.capacity() >= 2);
Run
source

pub fn entry(&mut self, key: K) -> Entry<'_, K, V>

在 map 中获取给定键的对应项,以进行就地操作。

Examples
use std::collections::HashMap;

let mut letters = HashMap::new();

for ch in "a short treatise on fungi".chars() {
    letters.entry(ch).and_modify(|counter| *counter += 1).or_insert(1);
}

assert_eq!(letters[&'s'], 2);
assert_eq!(letters[&'t'], 3);
assert_eq!(letters[&'u'], 1);
assert_eq!(letters.get(&'y'), None);
Run
source

pub fn get<Q>(&self, k: &Q) -> Option<&V>where K: Borrow<Q>, Q: Hash + Eq + ?Sized,

返回与键对应的值的引用。

键可以是 map 键类型的任何借用形式,但是借用形式上的 HashEq 必须与键的类型匹配。

Examples
use std::collections::HashMap;

let mut map = HashMap::new();
map.insert(1, "a");
assert_eq!(map.get(&1), Some(&"a"));
assert_eq!(map.get(&2), None);
Run
1.40.0 · source

pub fn get_key_value<Q>(&self, k: &Q) -> Option<(&K, &V)>where K: Borrow<Q>, Q: Hash + Eq + ?Sized,

返回与提供的键相对应的键值对。

提供的键可以是 map 的键类型的任何借用形式,但是借用形式上的 HashEq 必须与该键的类型匹配。

Examples
use std::collections::HashMap;

let mut map = HashMap::new();
map.insert(1, "a");
assert_eq!(map.get_key_value(&1), Some((&1, &"a")));
assert_eq!(map.get_key_value(&2), None);
Run
source

pub fn get_many_mut<Q, const N: usize>( &mut self, ks: [&Q; N] ) -> Option<[&mut V; N]>where K: Borrow<Q>, Q: Hash + Eq + ?Sized,

🔬This is a nightly-only experimental API. (map_many_mut #97601)

尝试立即获取 map 中的 N 值的异常引用。

返回一个长度为 N 的数组,其中包含每个查询的结果。 为了稳健性,最多将一个错误引用返回为任何值。 如果任何键重复或丢失,将返回 None

Examples
#![feature(map_many_mut)]
use std::collections::HashMap;

let mut libraries = HashMap::new();
libraries.insert("Bodleian Library".to_string(), 1602);
libraries.insert("Athenæum".to_string(), 1807);
libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
libraries.insert("Library of Congress".to_string(), 1800);

let got = libraries.get_many_mut([
    "Athenæum",
    "Library of Congress",
]);
assert_eq!(
    got,
    Some([
        &mut 1807,
        &mut 1800,
    ]),
);

// 缺少键会导致 None
let got = libraries.get_many_mut([
    "Athenæum",
    "New York Public Library",
]);
assert_eq!(got, None);

// 重复的键会导致 None
let got = libraries.get_many_mut([
    "Athenæum",
    "Athenæum",
]);
assert_eq!(got, None);
Run
source

pub unsafe fn get_many_unchecked_mut<Q, const N: usize>( &mut self, ks: [&Q; N] ) -> Option<[&mut V; N]>where K: Borrow<Q>, Q: Hash + Eq + ?Sized,

🔬This is a nightly-only experimental API. (map_many_mut #97601)

尝试立即获取 X 引用到 map 中的 N 值,而不验证这些值是否唯一。

返回一个长度为 N 的数组,其中包含每个查询的结果。 如果缺少任何键,将返回 None

有关安全的替代方案,请参见 get_many_mut

Safety

使用重叠键调用此方法是 undefined behavior,即使不使用生成的引用。

Examples
#![feature(map_many_mut)]
use std::collections::HashMap;

let mut libraries = HashMap::new();
libraries.insert("Bodleian Library".to_string(), 1602);
libraries.insert("Athenæum".to_string(), 1807);
libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
libraries.insert("Library of Congress".to_string(), 1800);

let got = libraries.get_many_mut([
    "Athenæum",
    "Library of Congress",
]);
assert_eq!(
    got,
    Some([
        &mut 1807,
        &mut 1800,
    ]),
);

// 缺少键会导致 None
let got = libraries.get_many_mut([
    "Athenæum",
    "New York Public Library",
]);
assert_eq!(got, None);
Run
source

pub fn contains_key<Q>(&self, k: &Q) -> boolwhere K: Borrow<Q>, Q: Hash + Eq + ?Sized,

如果 map 包含指定键的值,则返回 true

键可以是 map 键类型的任何借用形式,但是借用形式上的 HashEq 必须与键的类型匹配。

Examples
use std::collections::HashMap;

let mut map = HashMap::new();
map.insert(1, "a");
assert_eq!(map.contains_key(&1), true);
assert_eq!(map.contains_key(&2), false);
Run
source

pub fn get_mut<Q>(&mut self, k: &Q) -> Option<&mut V>where K: Borrow<Q>, Q: Hash + Eq + ?Sized,

返回与键对应的值的可变引用。

键可以是 map 键类型的任何借用形式,但是借用形式上的 HashEq 必须与键的类型匹配。

Examples
use std::collections::HashMap;

let mut map = HashMap::new();
map.insert(1, "a");
if let Some(x) = map.get_mut(&1) {
    *x = "b";
}
assert_eq!(map[&1], "b");
Run
source

pub fn insert(&mut self, k: K, v: V) -> Option<V>

将键值对插入 map。

如果 map 不存在此键,则返回 None

如果 map 确实存在此键,则更新值,并返回旧值。 但是,键不会更新。对于不能相同的 == 类型来说,这一点很重要。

有关更多信息,请参见 模块级文档

Examples
use std::collections::HashMap;

let mut map = HashMap::new();
assert_eq!(map.insert(37, "a"), None);
assert_eq!(map.is_empty(), false);

map.insert(37, "b");
assert_eq!(map.insert(37, "c"), Some("b"));
assert_eq!(map[&37], "c");
Run
source

pub fn try_insert( &mut self, key: K, value: V ) -> Result<&mut V, OccupiedError<'_, K, V>>

🔬This is a nightly-only experimental API. (map_try_insert #82766)

尝试将键值对插入到 map 中,并向条目中的值返回变量引用。

如果 map 已经存在此键,则不进行任何更新,并返回包含占用项和值的错误。

Examples

基本用法:

#![feature(map_try_insert)]

use std::collections::HashMap;

let mut map = HashMap::new();
assert_eq!(map.try_insert(37, "a").unwrap(), &"a");

let err = map.try_insert(37, "b").unwrap_err();
assert_eq!(err.entry.key(), &37);
assert_eq!(err.entry.get(), &"a");
assert_eq!(err.value, "b");
Run
source

pub fn remove<Q>(&mut self, k: &Q) -> Option<V>where K: Borrow<Q>, Q: Hash + Eq + ?Sized,

从 map 中删除一个键,如果该键以前在 map 中,则返回该键的值。

键可以是 map 键类型的任何借用形式,但是借用形式上的 HashEq 必须与键的类型匹配。

Examples
use std::collections::HashMap;

let mut map = HashMap::new();
map.insert(1, "a");
assert_eq!(map.remove(&1), Some("a"));
assert_eq!(map.remove(&1), None);
Run
1.27.0 · source

pub fn remove_entry<Q>(&mut self, k: &Q) -> Option<(K, V)>where K: Borrow<Q>, Q: Hash + Eq + ?Sized,

从 map 中删除一个键,如果该键以前在 map 中,则返回存储的键和值。

键可以是 map 键类型的任何借用形式,但是借用形式上的 HashEq 必须与键的类型匹配。

Examples
use std::collections::HashMap;

let mut map = HashMap::new();
map.insert(1, "a");
assert_eq!(map.remove_entry(&1), Some((1, "a")));
assert_eq!(map.remove(&1), None);
Run
source§

impl<K, V, S> HashMap<K, V, S>where S: BuildHasher,

source

pub fn raw_entry_mut(&mut self) -> RawEntryBuilderMut<'_, K, V, S>

🔬This is a nightly-only experimental API. (hash_raw_entry #56167)

为 HashMap 创建原始条目构建器。

原始条目为搜索和操作 map 提供了最低级别的控制。必须使用哈希将其手动初始化,然后进行手动搜索。 此后,插入空条目仍然需要提供一个拥有的键。

原始条目对于以下特殊情况很有用:

  • 哈希记忆
  • 推迟创建拥有的键,直到知道它是必需的为止
  • 使用不适用于借用 trait 的搜索键
  • 在不使用 newtype 包装器的情况下使用自定义比较逻辑

因为原始条目提供了更多的灵活控制,所以将 HashMap 置于不一致状态要容易得多,这虽然具有内存安全性,但会导致 map 产生看似随机的结果。 如果可能,应首选更高级别且更简单的 API,例如 entry

特别是,用于初始化原始条目的哈希必须仍然与最终存储在条目中的键的哈希保持一致。 这是因为 HashMap 的实现在调整大小时可能需要重新计算哈希,此时只有键可用。

原始条目为变量提供了可变的访问权限。 这不能用于修改键的比较或散列方式,因为映射不会重新评估键应该去的位置,这意味着如果它们的位置不反映它们的状态,它们可能会丢失。

例如,如果您更改一个键以使 map 现在包含比较相等的键,则搜索可能会开始不规律地进行,两个键彼此相互掩盖。 实现可以自由地假设不会发生这种情况 (在内存安全性的范围内)。

source

pub fn raw_entry(&self) -> RawEntryBuilder<'_, K, V, S>

🔬This is a nightly-only experimental API. (hash_raw_entry #56167)

为 HashMap 创建一个原始的不可变条目构建器。

原始条目为搜索和操作 map 提供了最低级别的控制。 必须使用哈希将其手动初始化,然后进行手动搜索。

这对于

  • 哈希记忆
  • 使用不适用于借用 trait 的搜索键
  • 在不使用 newtype 包装器的情况下使用自定义比较逻辑

除非您处于这种情况下,否则应首选更高级别且更简单的 API,例如 get

不可变的原始条目用途非常有限; 您可能需要 raw_entry_mut

Trait Implementations§

source§

impl<K, V, S> Clone for HashMap<K, V, S>where K: Clone, V: Clone, S: Clone,

source§

fn clone(&self) -> Self

返回值的副本。 Read more
source§

fn clone_from(&mut self, other: &Self)

source 执行复制分配。 Read more
source§

impl<K, V, S> Debug for HashMap<K, V, S>where K: Debug, V: Debug,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

使用给定的格式化程序格式化该值。 Read more
source§

impl<K, V, S> Default for HashMap<K, V, S>where S: Default,

source§

fn default() -> HashMap<K, V, S>

创建一个空的 HashMap<K, V, S>,其哈希值为 Default

1.4.0 · source§

impl<'a, K, V, S> Extend<(&'a K, &'a V)> for HashMap<K, V, S>where K: Eq + Hash + Copy, V: Copy, S: BuildHasher,

source§

fn extend<T: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: T)

使用迭代器的内容扩展集合。 Read more
source§

fn extend_one(&mut self, (k, v): (&'a K, &'a V))

🔬This is a nightly-only experimental API. (extend_one #72631)
用一个元素扩展一个集合。
source§

fn extend_reserve(&mut self, additional: usize)

🔬This is a nightly-only experimental API. (extend_one #72631)
在集合中为给定数量的附加元素保留容量。 Read more
source§

impl<K, V, S> Extend<(K, V)> for HashMap<K, V, S>where K: Eq + Hash, S: BuildHasher,

插入迭代器中的所有新键值,并用迭代器返回的新值替换现有键中的值。

source§

fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T)

使用迭代器的内容扩展集合。 Read more
source§

fn extend_one(&mut self, (k, v): (K, V))

🔬This is a nightly-only experimental API. (extend_one #72631)
用一个元素扩展一个集合。
source§

fn extend_reserve(&mut self, additional: usize)

🔬This is a nightly-only experimental API. (extend_one #72631)
在集合中为给定数量的附加元素保留容量。 Read more
1.56.0 · source§

impl<K, V, const N: usize> From<[(K, V); N]> for HashMap<K, V, RandomState>where K: Eq + Hash,

source§

fn from(arr: [(K, V); N]) -> Self

Examples
use std::collections::HashMap;

let map1 = HashMap::from([(1, 2), (3, 4)]);
let map2: HashMap<_, _> = [(1, 2), (3, 4)].into();
assert_eq!(map1, map2);
Run
source§

impl<K, V, S> FromIterator<(K, V)> for HashMap<K, V, S>where K: Eq + Hash, S: BuildHasher + Default,

source§

fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> HashMap<K, V, S>

从迭代器创建一个值。 Read more
source§

impl<K, Q, V, S> Index<&Q> for HashMap<K, V, S>where K: Eq + Hash + Borrow<Q>, Q: Eq + Hash + ?Sized, S: BuildHasher,

source§

fn index(&self, key: &Q) -> &V

返回与提供的键对应的值的引用。

Panics

如果键不在 HashMap 中,就会出现 panic。

§

type Output = V

索引后返回的类型。
source§

impl<'a, K, V, S> IntoIterator for &'a HashMap<K, V, S>

§

type Item = (&'a K, &'a V)

被迭代的元素的类型。
§

type IntoIter = Iter<'a, K, V>

我们将其变成哪种迭代器?
source§

fn into_iter(self) -> Iter<'a, K, V>

从一个值创建一个迭代器。 Read more
source§

impl<'a, K, V, S> IntoIterator for &'a mut HashMap<K, V, S>

§

type Item = (&'a K, &'a mut V)

被迭代的元素的类型。
§

type IntoIter = IterMut<'a, K, V>

我们将其变成哪种迭代器?
source§

fn into_iter(self) -> IterMut<'a, K, V>

从一个值创建一个迭代器。 Read more
source§

impl<K, V, S> IntoIterator for HashMap<K, V, S>

source§

fn into_iter(self) -> IntoIter<K, V>

创建一个消耗迭代器,即一个将任意键值对以任意顺序移出 map 的迭代器。 调用后不能使用 map。

Examples
use std::collections::HashMap;

let map = HashMap::from([
    ("a", 1),
    ("b", 2),
    ("c", 3),
]);

// .iter() 无法使用
let vec: Vec<(&str, i32)> = map.into_iter().collect();
Run
§

type Item = (K, V)

被迭代的元素的类型。
§

type IntoIter = IntoIter<K, V>

我们将其变成哪种迭代器?
source§

impl<K, V, S> PartialEq<HashMap<K, V, S>> for HashMap<K, V, S>where K: Eq + Hash, V: PartialEq, S: BuildHasher,

source§

fn eq(&self, other: &HashMap<K, V, S>) -> bool

此方法测试 selfother 值是否相等,并由 == 使用。
source§

fn ne(&self, other: &Rhs) -> bool

此方法测试 !=。 默认实现几乎总是足够的,并且不应在没有充分理由的情况下被覆盖。
source§

impl<K, V, S> Eq for HashMap<K, V, S>where K: Eq + Hash, V: Eq, S: BuildHasher,

1.36.0 · source§

impl<K, V, S> UnwindSafe for HashMap<K, V, S>where K: UnwindSafe, V: UnwindSafe, S: UnwindSafe,

Auto Trait Implementations§

§

impl<K, V, S> RefUnwindSafe for HashMap<K, V, S>where K: RefUnwindSafe, S: RefUnwindSafe, V: RefUnwindSafe,

§

impl<K, V, S> Send for HashMap<K, V, S>where K: Send, S: Send, V: Send,

§

impl<K, V, S> Sync for HashMap<K, V, S>where K: Sync, S: Sync, V: Sync,

§

impl<K, V, S> Unpin for HashMap<K, V, S>where K: Unpin, S: Unpin, V: Unpin,

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

获取 selfTypeIdRead more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

从拥有的值中一成不变地借用。 Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

从拥有的值中借用。 Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

返回未更改的参数。

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

调用 U::from(self)

也就是说,这种转换是 From<T> for U 实现选择执行的任何操作。

source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

获得所有权后的结果类型。
source§

fn to_owned(&self) -> T

从借用的数据创建拥有的数据,通常是通过克隆。 Read more
source§

fn clone_into(&self, target: &mut T)

使用借来的数据来替换拥有的数据,通常是通过克隆。 Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

发生转换错误时返回的类型。
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

执行转换。
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

发生转换错误时返回的类型。
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

执行转换。