为了账号安全,请及时绑定邮箱和手机立即绑定

独立迭代时,无序哈希映射中的键和值是否对齐?

独立迭代时,无序哈希映射中的键和值是否对齐?

江户川乱折腾 2022-06-23 16:00:47
我已经看到了涉及该主题的答案,但想查找是否有人有任何示例,其中您从哈希映射派生的键集和值列表将具有不同顺序的键和值。我知道条目本身在哈希图中可能有未定义的顺序,但是键和值的列表是否可以相互乱序?这是一个简短的片段以进行澄清:public class App {    public static void main(String[] args) {        Map<String,String> stateCapitols = new HashMap<>();        stateCapitols.put("AL", "Montgomery");        stateCapitols.put("AK", "Juneau");        stateCapitols.put("CO", "Denver");        stateCapitols.put("FL", "Tallahassee");        stateCapitols.put("Indiana", "Indianapolis");        stateCapitols.keySet().stream().forEach(System.out::println);        System.out.println();        stateCapitols.values().stream().forEach(System.out::println);    }}在上面的示例中,是否有任何方式AL可能出现在与Denver(或任何其他值)相同的位置?
查看完整描述

2 回答

?
猛跑小猪

TA贡献1858条经验 获得超8个赞

HashMap 不保证其迭代顺序。原则上(即规范允许)键的顺序是可能的,例如,从一个迭代到下一个迭代,即使映射的内容没有改变,或者迭代顺序为键与对应值的迭代顺序不同。

这在HashMap规范中有说明:

此类不保证地图的顺序;特别是,它不保证订单会随着时间的推移保持不变。

在实践中,如果 HashMap 的初始化和填充方式完全相同,则 HashMap 的迭代顺序从一次迭代到下一次,甚至从一次 JVM 调用到下一次都是稳定的。但是,应用程序依赖于此是不明智的。创建具有不同初始大小或加载因子的 HashMap 会影响迭代顺序,即使映射填充了相同的内容。HashMap 实现确实会不时更改,这也会影响迭代顺序。即使在 JDK 的补丁或错误修复版本中也会发生此类更改。不幸的是,历史表明,当迭代顺序发生变化时,应用程序会中断。因此,健壮的应用程序应该努力避免对 HashMap 迭代顺序产生任何依赖。

这在实践中很难做到。我知道 JDK 的一个(非公开)版本具有随机化 HashMap 的迭代顺序的测试模式。这可能有助于消除这种依赖关系。

如果您需要在迭代时关联 HashMap 的键和值,请获取 HashMap 的 entrySet() 并对其进行迭代。它提供映射条目(键值对),因此键和值之间的关系得以保留。

JDK 中的替代 Map 实现提供了良好定义的迭代顺序。TreeMap 和 ConcurrentSkipListMap 根据提供的比较方法对它们的条目进行排序。LinkedHashMap 提供基于插入顺序的迭代顺序。(它还提供了一种按访问顺序进行迭代的模式,这有时很有用,但其行为往往令人惊讶。)

请注意,Java 9 中引入的不可修改集合(Set.of、Map.of 等)提供了随机迭代顺序。JVM 的一次运行与下一次运行的顺序不同。这应该有助于应用程序避免对迭代顺序产生无意的依赖。


查看完整回答
反对 回复 2022-06-23
?
繁星淼淼

TA贡献1775条经验 获得超11个赞

让我们再看一下关于Map合约中迭代顺序的 Java SE API 语言:

一些地图实现,如 TreeMap 类,对它们的顺序做出特定的保证;其他的,比如 HashMap 类,不这样做。

并且HashMap

此类不保证地图的顺序;特别是,它不保证订单会随着时间的推移保持不变。

由于明确指出 HashMap 迭代器没有顺序,因此不能假设即使在对同一方法的调用之间迭代也将是稳定的,更不用说在调用不同方法keySet()values().

有帮助的是,Map有一种方法entrySet()可以完全满足您的需要:它以配对键和值的方式迭代映射内容。这是在您需要依赖该对的两个部分时使用的方法。

随着对 Java 许可的更改现在生效,那些认为他们可能总是使用 Oracle 的 Java 实现的个人和组织现在正在寻找替代实现。依赖单一实现的不成文细节是极其危险的,现在比甲骨文的许可和定价变化之前更是如此。


查看完整回答
反对 回复 2022-06-23
  • 2 回答
  • 0 关注
  • 143 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号