程序运行之间是否有任何HashMap实现具有一致的排序?

时间:2017-08-26 10:29:41

标签: hashmap rust

我观察到HashMap具有不同的元素顺序,即使在下一个程序开始时具有相同的数据。看起来HashMap使用一些绝对地址来排序元素。是否有任何其他HashMap实现,如果插入相同的数据,则具有相同的行为?

4 个答案:

答案 0 :(得分:7)

  

我观察到HashMap具有不同的元素顺序,即使在下一个程序开始时具有相同的数据。

您不必观察任何事情,这是documented by HashMap

  

默认情况下,HashMap使用选定的哈希算法来提供对HashDoS攻击的抵抗。该算法是随机播种的,并且合理的尽最大努力从主机提供的高质量,安全的随机源生成该种子,而不会阻止该程序。

值得注意的是,这意味着在相同程序运行中具有相同插入值集的两个HashMap可能会有不同的顺序:

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));
}

文档还告诉您如何解决问题:

  

可以使用HashMapdefaultwith_hasher方法在每{ - 1}}基础上替换散列算法。 crates.io上有许多替代算法,例如fnv crate。

自从我致力于twox-hash以来,我将以此为例展示:

with_capacity_and_hasher

话虽如此,依赖于use std::hash::BuildHasherDefault; use std::collections::HashMap; use twox_hash::XxHash; let mut hash: HashMap<_, _, BuildHasherDefault<XxHash>> = Default::default(); hash.insert(42, "the answer"); assert_eq!(hash.get(&42), Some(&"the answer")); 的顺序听起来像个坏主意。也许您应该使用不同的数据结构,例如BTreeMap

在其他情况下,您实际上关心插入的顺序。为此,indexmap crate是合适的。

答案 1 :(得分:2)

我相信linked-hash-map是事实上的箱子。

答案 2 :(得分:1)

HashMap::with_hasher()与默认RandomState以外的其他内容一起使用。

答案 3 :(得分:0)

内置的 BTreeMap 是一个很好的选择。

我在 assert_eq! 中遇到了类似的问题。 diff每次都是随机排序,给HashMap调试带来了困难,但BTreeMap有key排序,所以不存在这个问题。

(来源:https://users.rust-lang.org/t/sort-hashmap-data-by-keys/37095/2