java 在哪种情况下,HashMap keySet()排序是不确定的

qfe3c7zg  于 2023-10-14  发布在  Java
关注(0)|答案(2)|浏览(91)

文件https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html
这个类不保证Map的顺序;特别是,它不保证顺序随时间保持不变。
但是我做了个实验

var first = new HashMap<String, Object>();
first.put("a", 1)
first.put("b", 2);
first.put("c", null)

first.keySet()顺序始终为[a, b, c]
所以,如果我有StringInteger作为HashMap的键,那么对于任何其他HashMap示例,对于相同的键和值,顺序是否相同?

oalqel3c

oalqel3c1#

在哪种情况下HashMap::keySet()是非确定性排序的?
总之...当任何先决条件1,2或3(下面!)都不是真的。
javadoc说了它说的话。HashMap实现不保证密钥集的任何特定顺序。
事实上,javadoc不保证顺序并不意味着在某些情况下顺序无法预测。
你的观察证实了这一点!
在实践中,如果以下所有条件都为真,则HashMap中的键的顺序将是 * 确定性的 *:

  1. HashMap实现不会改变1。
    1.关键类equalshashCode方法遵循Object javadoc中指定的相关不变量。(在某些情况下,也可能涉及compareTo方法。
    1.键类hashCode是基于键的值可预测的。
    此外,如果:
    1.Map是用相同的初始容量和负载系数创建的。
    1.键的插入(和删除)顺序相同。
    .您将重复获得相同的密钥集顺序。
    事实上,如果以上所有都是真的,并且你有关于HashMap实现等的完整信息/知识,那么你实际上可以 * 先验预测 * 100%准确的密钥顺序。
    注意,对于IntegerString,满足2和3。实际上,这两个类的javadoc指定了hashCode()返回的精确值。这就是为什么你在实验中看到这些键类型重复使用相同的键顺序。
    注意:您可能不应该在应用程序中使用这些属性,因为javadoc实际上并不保证它们。
    1 -或者更准确地说,当它不改变时。实际上,HashMap的实现在不同的Java版本之间发生了变化。因此,如果您在不同版本的Java平台上运行测试,则键的顺序可能会有所不同。也可以想象,HashMap的未来实现可能会被故意 * 非确定性...虽然我无法想象他们为什么要这么做
    2.这个过程如果用手工来做的话会非常繁琐和耗时,我不打算解释它。但是Why does a HashMap sometimes print in natural order可以帮助您了解需要做什么。
tgabmvqs

tgabmvqs2#

正如doc所建议的那样,顺序确实是不确定的。
尝试在HashMap中使用更多数据运行代码,以查看差异。
集合是无序的。
如果顺序是你的需求所必需的(在主数据结构中),尝试LinkedHashMap,它可以维护插入的顺序。(因为它在内部实现了LinkedList。
希望这对你有帮助。

相关问题