HashMap的keySet()、values(),不遍历只打印,键值对不对应?

作者站长头像
站长
· 阅读数 15

HashMap中keySet()、values(),不遍历只打印,键值对不对应?

public class test {
    public static void main(String[] args) {
        HashMap<String, Integer> map = new HashMap<>();
        map.put("Aa",1);
        map.put("BB",2);
        map.put("3",3);
        map.put("4",4);

        System.out.println(map.keySet());
        System.out.println(map.values());
    }
}

输出的结果是,结果看是对应的

[Aa, BB, 3, 4]
[1, 2, 3, 4]

gpt给出的解答是

在这个输出中,键和值似乎顺序匹配,但这仅仅是巧合。HashMap 的内部结构决定了其遍历顺序是不可预测的。虽然目前表现正常,但在某些情况下(例如,插入数据顺序不同、哈希冲突、重新哈希等情况下),keySet() 和 values() 的顺序可能不会对应。

求大佬解答,该怎么验证

回复
1个回答
avatar
test
2024-09-07

顺序是一样的。

OpenJDK 是开源的,直接看源码就好了:

https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/HashMap.java#L1627-L1640

keySet()values()entrySet() 三者调用的都是同一个 nextNode() 方法,同一个迭代器,顺序当然是一样的了。

我们讲 HashMap 顺序不固定一般指的是插入和遍历之间的顺序比较,而不是遍历键和遍历值之间的顺序比较。

但是有一个问题是,JDK 的 API 规范里并没有明确指出过,这三个遍历方法的顺序一定是保持一致的。也就是说,虽然现在你看到 OpenJDK/OracleJDK 现在是这样实现的,但不排除以后某个版本更新或者其他 JDK 的实现里,它顺序就变了(虽然我个人觉得这种可能性几乎没有)。因此从开发的角度来说,尽量不要依赖这种未定义的行为。如果你真的需要同时遍历键和值、且需要顺序保持一致,不是也提供了 entrySet() 方法么。

回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容