首页 课程 师资 教程 报名

一文告诉你HashMap是有序的吗

  • 2022-06-10 09:45:26
  • 1763次 赢咖4

相信大家对HashMap是什么已经有所了解,那么HashMap是有序的吗?赢咖4小编来为大家解答。

前提

首先说明:HashMap不保证插入顺序,但是循环遍历时,输出顺序是不会改变的。

代码说明

public class HashMapTest {
    public static void main(String[] args) {
        HashMap<String, String> map = new HashMap<>();
        map.put("aaa", "aaa");
        map.put("bbb", "bbb");
        map.put("ccc", "ccc");
        System.out.println("第一次输出:");
        for (Map.Entry<String, String> entry : map.entrySet()) {
            System.out.println(entry.getKey());
        }
        System.out.println("\n第二次输出:");
        for (Map.Entry<String, String> entry : map.entrySet()) {
            System.out.println(entry.getKey());
        }
    }
}

输出:

第一次输出:
aaa
ccc
bbb
第二次输出:
aaa
ccc
bbb

问题背景

项目开发过程中,遇到类似的如下代码,即,两个Map,put的key值相同,但是两个Map最后循环遍历输出的key顺序却不一样

public class HashMapTest {
    public static void main(String[] args) {
        HashMap<String, String> map1 = new HashMap<>();
        map1.put("123", "aaa");
        map1.put("23456", "bbb");
        System.out.println("map1的循环遍历");
        for (Map.Entry<String, String> entry : map1.entrySet()) {
            System.out.println(entry.getKey());
        }
        HashMap<String, String> map2 = new HashMap<>(map1.size());
        map2.put("123", "aaa");
        map2.put("23456", "bbb");
        System.out.println("map2的循环遍历");
        for (Map.Entry<String, String> entry : map2.entrySet()) {
            System.out.println(entry.getKey());
        }
    }
}

代码输出为:

map1的循环遍历
123
23456
map2的循环遍历
23456
123

HashMap的一些特性

HashMap的数据结构:数组+单链表,当存在hashCode相同的不同对象时,会将value以单链表的形式,往后追加。数组加快访问速度,单链表解决hash值冲突

调用put方法时,发生了什么:根据key的hashCode,计算出将key放入数组的index下标,index= (数组长度 - 1) & hashCode

HashMap循环遍历的顺序:根据数组顺序+单链表顺序进行输出。虽然遍历时,用的EntrySet,但是可以简单理解为,两层循环输出数据,外层循环为遍历数组,内层循环为遍历单链表

HashMap在初始化时,默认初始容量为16,以及默认的扩容因子0.75(在此处就不详细介绍了)

问题分析

基于如上HashMap的特性,仔细看map2的初始化,会发现

        HashMap<String, String> map2 = new HashMap<>(map1.size());

即:map2的初始化容量=map1.size()。

这个设置,导致相同的key,在put到map2时,计算出的index值,与map1中的不一样

因为计算index时,依赖于数组的长度(参考上面:put方法调用说明)

结论

若两个Map的初始化容量不一致,就算同时插入相同的key,最后输出的顺序,不一定一直

再结论

代码规范性挺重要的,想要依赖Map保持有序性,请使用LinkedHashMap

以上就是关于“一文告诉你HashMap是有序的吗”介绍,大家如果想了解更多相关知识,不妨来关注一下赢咖4的HashMap底层实现原理视频教程,里面的课程内容由浅到深,通俗易懂,相信对大家的学习一定会有所帮助的。

选你想看

你适合学Java吗?4大专业测评方法

代码逻辑 吸收能力 技术学习能力 综合素质

先测评确定适合在学习

在线申请免费测试名额
价值1998元实验班免费学
姓名
手机
提交