首页 > 其他分享 >HashMap也是可以有序的?

HashMap也是可以有序的?

时间:2024-03-15 09:56:19浏览次数:27  
标签:有序 数组 16 可以 key 65535 HashMap

前些天看到一个有意思的说法,当HashMap的key为Integer时,map就是有序的,我来研究一下。

我们都知道HashMap是无序的,TreeMap是有序的,数组和链表也是有序的,为啥会变成有序呢?我们先来随便测试一下

 

果然,key是0到100的时候都是有序的,不管使用keySet还是entrySet的形式遍历map,隐隐觉得不可能全都是有序的吧,扩大范围再试一下,果然,当key是在0到65535的时候才是有序的

我们来研究一下原理,为什么是0到65536

众所周知,HashMap是  数组 + 链表/红黑树来实现的,数组的下标是由key的hash及数组长度来确定的,

关键是hash值,是由key本身的hashCode(int值,32位),把这个值的高16位和低16位进行异或得到的(非官方说法,说是扰动函数,这样做能让确定数组下标的时候分布更离散,因为利用到了高16位的信息)

 而Integer的hashCode就是自身的数值,所以就能解释为什么是发生这个情况是在 key小于65535大于等于0的时候,因为这时候hashCode高16位全是0,高16和低16异或出来还是本身。

那是不是只要key是Integer,key的范围是0到65536,这个map就能变成有序了?

当然不是,还要看数组长度,当你是按key顺序一个一个add进去的时候,此时由于数组一直是比hash值大的,所以根本没有哈希碰撞,没有链表和红黑树什么事,此时HashMap退化成了一个数组

 

当然如果是你一开始就给HashMap的size设置为65535,然后往里put的key的范围是在0和65535中间,那输出还是按key的顺序来的

 

标签:有序,数组,16,可以,key,65535,HashMap
From: https://www.cnblogs.com/huainanyin/p/18074760

相关文章

  • Javaweb项目使用本地servlet启动,可以弹出主页,跳转到controller报404解决方案
    首先检查项目的资源路径,以及tomcat配置,有没有部署,上下文配置好如果问题依然出现,那么可以考虑tomcat版本与依赖不匹配,我用的是tomcat10,使用使用这个依赖,就解决了这个问题,jakarta.servletjakarta.servlet-api5.0.0provided,相应的匹配版本可以查询到。......
  • Windows压缩文件可以用 PowerShell中的Compress-Archive
    压缩单个文件Compress-Archive-Path"D:\tmp\test.txt"-DestinationPath"D:\tmp\test.zip"压缩多个文件Compress-Archive-Path"D:\tmp\test.txt","D:\tmp\test2.txt"-DestinationPath"D:\tmp\test2.zip"压缩文件夹Comp......
  • useImperativeHandle 可以用来暴露state属性吗?
    useImperativeHandle是ReactHooks中的一个API,它的主要作用是定制暴露给父组件的子组件实例的引用。通常与forwardRef配合使用,用于控制哪些属性或方法能够被父组件通过ref获取和操作。然而,useImperativeHandle并不能直接用来暴露state属性。它更多的是用来暴露可以被父组件调用......
  • 河北王校长源码之HashMap
    HashMap类结构继承AbstractMap<K,V>实现Map<K,V>Map基本方法实现Cloneable浅克隆实现Serializable序列化成员变量//默认初始化容量staticfinalintDEFAULT_INITIAL_CAPACITY=1<<4;//数组最大长度staticfinalintMAXIMUM_CAPAC......
  • 在Linux中,哪些命令可以管理系统服务,如启动、停止、重启一个服务?
    在Linux中,管理系统服务涉及到对运行中的进程或后台任务的启动、停止、重启等操作。这些操作通常通过特定的命令和工具来完成。下面详细说明了如何执行这些任务:1.启动服务使用service命令在早期的Linux发行版中,service命令是启动服务的主要方式。例如:service服务名start使......
  • leetcode.21 合并两个有序链表
     21.合并两个有序链表 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。  示例1:输入:l1=[1,2,4],l2=[1,3,4]输出:[1,1,2,3,4,4]示例2:输入:l1=[],l2=[]输出:[]示例3:输入:l1=[],l2=[0]输......
  • 数据结构——循环链表,双向链表,线性表和有序表的合并详解
    目录1.循环链表1.带尾指针循环链表的合并 代码示例:2.双向链表代码示例:  1.双向链表的插入​代码示例:2.双向链表的删除代码示例:3.单链表,循环链表,双向链表时间效率的比较4.顺序表和链表的比较 5.存储密度6.线性表的应用 1.线性表的合并​代码示例:2.有序表......
  • 为什么weak_ptr可以解决循环引用问题
    weak_ptr可以解决循环引用问题的主要原因在于它不会增加对象的引用计数,从而不会导致对象无法被销毁。在循环引用中,两个或多个对象相互持有对方的shared_ptr,导致对象的引用计数始终不为零,即使程序不再使用这些对象,它们也无法被销毁,从而造成内存泄漏。weak_ptr的引入可以打破这......
  • [Dubbo] Dubbo 反序列化将Pair转化成HashMap的问题
    问题描述Dubbo在3.2.x版本中,类检查级别默认是STRICT3.1版本中默认为WARN告警级别,3.2版本中默认为STRICT严格检查级别。不配置的情况下,会将名单以外的类型转化成Map。如何支持Pair的序列化和反序列化dubbo.application.serialize-check-status=WARN新建允许的名......
  • volatile关键字是如何确保多线程环境下变量的可见性和有序性
    VOLATILE关键字在JAVA中用于确保多线程环境下的变量可见性和一定程度的有序性,其具体实现机制基于JAVA内存模型(JAVAMEMORYMODEL,JMM):可见性:当一个线程修改了标记为volatile的共享变量时,它会强制将这个变量值从当前线程的工作内存刷新回主内存。同时,其他线程在读取该volatil......