【问题标题】:Are there any HashMap implementations with consistent ordering between program runs?程序运行之间是否有任何具有一致顺序的 HashMap 实现?
【发布时间】:2018-02-04 06:30:53
【问题描述】:

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

【问题讨论】:

    标签: hashmap rust


    【解决方案1】:

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

    你不必观察任何东西,这里是documented by HashMap

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

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

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

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

    可以使用defaultwith_hasherwith_capacity_and_hasher 方法在每个HashMap 的基础上替换散列算法。 crates.io 上提供了许多替代算法,例如 fnv crate。

    由于我在 twox-hash 工作,我将以此为例:

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

    话虽如此,依赖HashMap的顺序听起来是个坏主意。也许您应该使用不同的数据结构,例如BTreeMap

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

    【讨论】:

    • 其实indexmap中的迭代顺序并不是严格的插入顺序。为什么?因为在删除元素时,最后插入的元素与要删除的元素交换。对于给定的插入/删除序列,它仍然是完全确定的。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      我在 assert_eq! 中遇到了类似的问题! diff 每次都是随机顺序,HashMap 调试比较困难,但是 BTreeMap 对 key 进行了排序,所以不存在这个问题。

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

        • 例如...?
        猜你喜欢
        • 1970-01-01
        • 2010-12-25
        • 1970-01-01
        • 2017-06-20
        • 2021-01-25
        • 1970-01-01
        • 2018-01-27
        • 1970-01-01
        相关资源
        最近更新 更多