Are there any HashMap implementations with consistent ordering between program runs?

生来就可爱ヽ(ⅴ<●) 提交于 2020-08-07 04:58:21

问题


I've observed that HashMap has a different order of elements even with the same data on the next program start. It looks like HashMap uses some absolute addresses to sort elements. Is there any other HashMap implementation, which has the same behaviour if the same data was inserted?


回答1:


I believe linked-hash-map is the de facto crate for this.




回答2:


I've observed that HashMap has a different order of elements even with the same data on the next program start.

You don't have to observe anything, this is documented by HashMap:

By default, HashMap uses a hashing algorithm selected to provide resistance against HashDoS attacks. The algorithm is randomly seeded, and a reasonable best-effort is made to generate this seed from a high quality, secure source of randomness provided by the host without blocking the program.

It's worth noting that this means that two HashMaps with the same set of inserted values in the same program run will likely have different ordering:

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

The documentation also tells you how to address the problem:

The hashing algorithm can be replaced on a per-HashMap basis using the default, with_hasher, and with_capacity_and_hasher methods. Many alternative algorithms are available on crates.io, such as the fnv crate.

Since I worked on twox-hash, I'll show that as an example:

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

That being said, relying on the order of a HashMap sounds like a bad idea. Perhaps you should use a different data structure, such as a BTreeMap.

In other cases, you actually care about the order of insertion. For that, the indexmap crate is appropriate.




回答3:


Use HashMap::with_hasher() with something other than the default RandomState.



来源:https://stackoverflow.com/questions/45894401/are-there-any-hashmap-implementations-with-consistent-ordering-between-program-r

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!