文件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]
所以,如果我有String
或Integer
作为HashMap
的键,那么对于任何其他HashMap
示例,对于相同的键和值,顺序是否相同?
2条答案
按热度按时间oalqel3c1#
在哪种情况下
HashMap::keySet()
是非确定性排序的?总之...当任何先决条件1,2或3(下面!)都不是真的。
javadoc说了它说的话。
HashMap
实现不保证密钥集的任何特定顺序。事实上,javadoc不保证顺序并不意味着在某些情况下顺序无法预测。
你的观察证实了这一点!
在实践中,如果以下所有条件都为真,则
HashMap
中的键的顺序将是 * 确定性的 *:HashMap
实现不会改变1。1.关键类
equals
和hashCode
方法遵循Object
javadoc中指定的相关不变量。(在某些情况下,也可能涉及compareTo
方法。1.键类
hashCode
是基于键的值可预测的。此外,如果:
1.Map是用相同的初始容量和负载系数创建的。
1.键的插入(和删除)顺序相同。
.您将重复获得相同的密钥集顺序。
事实上,如果以上所有都是真的,并且你有关于
HashMap
实现等的完整信息/知识,那么你实际上可以 * 先验预测 * 100%准确的密钥顺序。注意,对于
Integer
和String
,满足2和3。实际上,这两个类的javadoc指定了hashCode()
返回的精确值。这就是为什么你在实验中看到这些键类型重复使用相同的键顺序。注意:您可能不应该在应用程序中使用这些属性,因为javadoc实际上并不保证它们。
1 -或者更准确地说,当它不改变时。实际上,
HashMap
的实现在不同的Java版本之间发生了变化。因此,如果您在不同版本的Java平台上运行测试,则键的顺序可能会有所不同。也可以想象,HashMap
的未来实现可能会被故意 * 非确定性...虽然我无法想象他们为什么要这么做2.这个过程如果用手工来做的话会非常繁琐和耗时,我不打算解释它。但是Why does a HashMap sometimes print in natural order可以帮助您了解需要做什么。
tgabmvqs2#
正如doc所建议的那样,顺序确实是不确定的。
尝试在HashMap中使用更多数据运行代码,以查看差异。
集合是无序的。
如果顺序是你的需求所必需的(在主数据结构中),尝试LinkedHashMap,它可以维护插入的顺序。(因为它在内部实现了LinkedList。
希望这对你有帮助。