作者:M7y4C8r2a6z4y | 来源:互联网 | 2023-01-21 12:36
我观察到,HashMap
即使在下一个程序启动时使用相同的数据,也会有不同的元素顺序.它看起来像HashMap
使用一些绝对地址来排序元素.是否有其他HashMap
实现,如果插入相同的数据,它们具有相同的行为?
1> Shepmaster..:
我观察到,HashMap
即使在下一个程序启动时使用相同的数据,也会有不同的元素顺序.
您不需要观察任何事情,这可以通过HashMap
以下方式记录:
默认情况下,HashMap
使用选定的散列算法来提供对HashDoS攻击的抵抗.该算法是随机播种的,并且合理的尽最大努力从主机提供的高质量,安全的随机源生成该种子而不阻塞该程序.
值得注意的是,这意味着HashMap
在同一程序运行中具有相同插入值集的两个s 可能具有不同的排序:
use std::collections::HashMap;
fn main() {
let a = (0..100).zip(100..200);
let hash_one: HashMap<_, _> = a.clone().collect();
let hash_two: HashMap<_, _> = a.clone().collect();
// prints "false", most of the time
println!("{}", hash_one.into_iter().eq(hash_two));
}
该文档还告诉您如何解决问题:
散列算法可以以每个上被替换HashMap
的基础使用default
,with_hasher
以及with_capacity_and_hasher
方法.crates.io上有许多替代算法,例如fnv crate.
由于我在使用twox-hash,我将以此为例进行说明:
use std::hash::BuildHasherDefault;
use std::collections::HashMap;
use twox_hash::XxHash;
let mut hash: HashMap<_, _, BuildHasherDefault> = Default::default();
hash.insert(42, "the answer");
assert_eq!(hash.get(&42), Some(&"the answer"));
话虽这么说,依靠HashMap
听起来像一个坏主意的顺序.也许您应该使用不同的数据结构,例如a BTreeMap
.
在其他情况下,您实际上关心插入的顺序.为此,indexmap包是合适的.