对于String作为 HashMap key 的一些思考。
一切都是突发奇想。
先说我的结论:String作为key的时候,是放入对象,对象改变会造成影响。(感觉像废话,但是结论是需要证明出来的)
首先要先补充一些知识点:
- String 底层是用 final 关键字,理论上来说是不可能更改的,如果你将引用指向新的字符串,会创建一个新的 String 对象。
- String 底层其实是维护一个 byte 数组,我们知道,对于 final 修饰的数组,虽然地址不可改变,但是数组值是可以改变的。
- 理论上,反射可以破坏除了枚举的一切东西。
- HashMap 对于新key的插入,会有一个判重的操作,如果重复,会覆盖。
这篇文章主要是思考,主要是源于其他大佬博客的一句话:
“因为 String 的 hash 值经常被使用,例如 String 用做 HashMap 的 key。不可变的特性可以使得 hash 值也不可变,因此只需要进行一次计算。”
这句话没有什么问题,但是我在想,当一个 String 对象当成key之后,由于他的不可变特性如何去验证他。
HashMap<String,Object> map = new HashMap<>();String a = "a";map.put(a,1);map.put("b",2);System.out.println(map.toString());a = "c";map.put(a,3);System.out.println(map);
首先到这里应该都很好懂,输出应该是:
{a=1, b=2}
{a=1, b=2, c=3}
接着利用反射去更改 a 的值,使他变成字符串 “a”;
Field array=a.getClass().getDeclaredField("value");array.setAccessible(true);byte[] arr=(byte[])array.get(a);arr[0]='a';System.out.println(map);
得到结果
{a=1, b=2, a=3}
这时候,有些朋友可能就有点发蒙了,不说会覆盖吗。
那当我分别去get()的时候,会获取以下结果。
get("a") ==> 1get("b") ==> 2get(a) ==> 3get("c") ==> 3
理由很简单,其实对象a用的是字符串“c”的地址,而hashcode又是依靠地址计算的,也就是说对象a的地址并没有改变,只是值变化了而已,而“c”已经创建过,在常量池有一个地址,“c”的地址与现在的对象 a 地址相同,hashcode也相同,所以后两个表达式的输出结果相同。
还可以扩展:
String lk = "c";map.put(lk,"4");System.out.println(map.toString());
输出:{a=1, b=2, a=4}
上面说了,其实“c”已经创建过,在常量池有一个地址,将一个新的引用 lk 指向他之后,其实地址是相同的,hashcode也是相同的,put 的时候,只会去覆盖他的值,但是key的样子依然不会变。
啊,又是增涨奇怪知识的一天。
对于String作为 HashMap key 的一些思考。相关推荐
- java Hashset去重原理及HashMap key唯一原理
如下,set中添加重复元素是不可以的,如下 php被添加了2次,但是输出的时候只有一次,那么其去重的原理是什么呢? public class Test {public static void main ...
- HashMap key是对象为什么取不到value值
文章目录 HashMap key是对象为什么取不到value值 场景重现 结果办法 验证 补充 HashMap key是对象为什么取不到value值 场景重现 Product类代码如下 public ...
- //身份证改名字问题选择HashMap,key对应vaule
// 在对集合中元素遍历删除时不要使用集合本事的remove方法,除非是单个移除: // 否则任何时候建议使用迭代器(Iterator)本身的remove方法对元素进行删除 // 注意事项:使用迭代器 ...
- python操作string类型的key的代码
操作环境: ubuntu16.04 python2.7 #-*- encoding:utf-8 -*- import sys reload(sys) sys.setdefaultencoding('u ...
- hashmap 允许key重复吗_Java HashMap key 可以重复吗?
Java HashMap key 可以重复吗? Java的HashMap中key是不可以重复的,如果重复添加的话,HashMap会自动覆盖key一样的数据,保证一个key对应一个value,使用时只要 ...
- 为什么 HashMap 常用 String 对象作 key
偶然的一次机会看到了这个题目,有一个网上的朋友说在面试的时候面到了这道题目,没有能给出解释.这里就谈一谈自己的理解. 在<Java 编程思想>中有这么一句话:设计 hashCode() 时 ...
- ArrayList ,LinkedList,Vector,StringBuilder,StringBuffer ,String,HashMap,LinkedHashMap,TreeMap
ArrayList ,LinkedList,Vector 区别和联系 从上面的类层次结构图中,我们可以发现他们都实现了List接口,它们使用起来非常相似.区别主要在于它们各自的实现,不同的实现导致了不 ...
- 由String.equals()方法引起的一系列思考
2019独角兽企业重金招聘Python工程师标准>>> 废话不多说直接贴String.euqals方法代码 public boolean equals(Object anObject ...
- com.netflix.hystrix.exception.HystrixRuntimeException: 类名#方法名(String,String) failed错误引起的一连串思考
这个错误是在看网上的视频资料学习时产生的,本来以为只是简单的远程调用方法错误,在找错误的过程中发现了不只是这个错误 首先 对于该错误本身是因为远程调用出错,我在认真检查了代码之后发现远程调用代码并没有 ...
最新文章
- php 云片网对接,php调用云片网接口发送短信的实现方法
- linux版视频转换软件,居家旅行必备的Linux视频转换工具
- IOS学习之 网络编程(10)--简单介绍ASI框架的使用
- tms570 can 接收大量数据_超全!嵌入式必懂的CAN总线一文讲通了
- html5添加渐变边框效果,《CSS3揭秘》上(边框,投影,渐变,条纹效果,蚂蚁行军)...
- 服务器之Apache和Tomcat和Nginx的理解和对比
- 电脑键盘上每个键的作用_键盘F键有什么作用 键盘F键作用介绍【详解】
- oracle ora-01476: 除数为 0,Oracle常见错误:ORA-01403 的根本原因和解决方案
- InsecureRequestWarning: Unverified HTTPS request is being made.解决方法
- 【CCCC】L3-022 地铁一日游 (30分),floyd+大模拟
- centen os7 安装并配置Nexus3.9.0
- mysql中根据经纬度求距离_mysql、java中根据经纬度计算距离
- 报文学习四(LLDP协议)
- 微信小程序开发者工具构建npm
- ggplot绘图之基本语法
- 派森学python_2019 年 1月 26 日 随笔档案 - 派森学python - 博客园
- 案例2:随机森林来填补缺失值
- html 萤火虫特效,jquery萤火虫飞舞动画特效插件
- 2.22 ACM模拟赛总结
- 《4DenoiseNet: Adverse Weather Denoising from Adjacent Point Clouds》
热门文章
- Qt5--学习笔记-+openCV2-客户端、服务端回环视频显示
- “神似充气娃娃”的人形机器人,made in China
- [WebGL入门]二十六,纹理绘图
- python之excel处理画图
- sift特征检测与匹配
- 城市交通的5D模式 | 不同尺度下研究的城市交通
- 荣欣Linux运维+Oracle DBA实战训练
- boost之内存管理
- 元宇宙将如何影响我们的投资、就业和生活方式?
- php时间戳 中文,PHP时间戳-WEB资讯专栏-DMOZ中文网站分类目录-免费收录各类优秀网站的中文网站目录....