浅析HashMap的存储数据无序性原因

浅析HashMap的存储数据无序性原因

众所周知,hashMap的put方法存储是无序的,不能根据自定义存放顺序来,如果需要有序则使用LinkedHashMap,如下面代码,

put时的顺序为:

12 -> 3 ->5 -> 16 -> 20 -> 21

循环遍历后的结果为:

16 -> 3 -> 20 -> 5 -> 21 -> 12

演示代码
public class HashMapTest {
    public static void main(String[] args) {

        Map<Integer,String> map=new HashMap();

        map.put(12,"abc");
        map.put(3,"abc");
        map.put(5,"abc");
        map.put(16,"abc");
        map.put(20,"abc");
        map.put(21,"abc");

        System.out.println("循环遍历结果:");
        for(Integer key:map.keySet()){
            System.out.print(key +" -> ");
        }
    }
}


循环遍历结果:
16 -> 3 -> 20 -> 5 -> 21 -> 12 

但其实不管执行多少遍,每次遍历结果都是同样的顺序: 16 -> 3 -> 20 -> 5 -> 21 -> 12 ,并没有改变。
那么就要理解HashMap在put值时候怎么存放的问题,以及为什么每次遍历结果都相同?
如图所示,HashMap底层是数组+链表的结构,每个数组默认大小是16,即0-15,在put方法存放值的时候,会根据key值大小来计算存放位置,
12%16=12,3%16=3,5%16=5,16%16=0,20%16=4,21%16=5
因为key=5存放在前,key=21 存放在后,虽然余数都是5,因为插入数据先后顺序不同,所以 key=21 的数据链表悬挂在key=5之后。循环遍历的结果就是: 16 -> 3 -> 20 -> 5 -> 21 -> 12

数据存放如下图所示:

在这里插入图片描述

更改一下key=21与key=5插入顺序

put时的顺序为:

21 -> 12 -> 3 ->5 -> 16 -> 20

循环遍历后的结果为:

16 -> 3 -> 20 -> 21 -> 5 -> 12

演示代码
public class HashMapTest {
    public static void main(String[] args) {

        Map<Integer,String> map=new HashMap();

        map.put(21,"abc");
        map.put(12,"abc");
        map.put(3,"abc");
        map.put(5,"abc");
        map.put(16,"abc");
        map.put(20,"abc");


        System.out.println("循环遍历结果:");
        for(Integer key:map.keySet()){
            System.out.print(key +" -> ");
        }
    }
}

循环遍历结果:
16 -> 3 -> 20 -> 21 -> 5 -> 12
数据存放如下图所示:

在这里插入图片描述

HashMap是一种常用的数据结构,用于存储键值对。它通过哈希函数将键映射到存储桶中,并使用链表或红黑树来解决哈希冲突。 下面是HashMap存储数据的过程: 1. 当我们向HashMap中插入一个键值对时,首先会根据键的哈希值计算出存储桶的索引位置。 2. 如果该索引位置上没有元素,则直接将键值对存储在该位置上。 3. 如果该索引位置上已经存在元素,则可能存在哈希冲突。HashMap使用链表或红黑树来解决哈希冲突。 - 如果链表长度小于8,则将新的键值对添加到链表的末尾。 - 如果链表长度大于等于8,则将链表转换为红黑树,以提高查找效率。 4. 当需要查找某个键对应的值时,HashMap会根据键的哈希值计算出存储桶的索引位置,并在该位置上进行查找。 - 如果该位置上是链表,则遍历链表进行线查找。 - 如果该位置上是红黑树,则使用红黑树的查找算法进行查找。 5. 当需要删除某个键值对时,HashMap会根据键的哈希值计算出存储桶的索引位置,并在该位置上进行删除操作。 - 如果该位置上是链表,则遍历链表进行删除。 - 如果该位置上是红黑树,则使用红黑树的删除算法进行删除。 总结一下,HashMap通过哈希函数将键映射到存储桶中,并使用链表或红黑树来解决哈希冲突。这样可以在常数时间内实现插入、查找和删除操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值