一切都是突发奇想。

先说我的结论:String作为key的时候,是放入对象,对象改变会造成影响。(感觉像废话,但是结论是需要证明出来的)

首先要先补充一些知识点:

  1. String 底层是用 final 关键字,理论上来说是不可能更改的,如果你将引用指向新的字符串,会创建一个新的 String 对象。
  2. String 底层其实是维护一个 byte 数组,我们知道,对于 final 修饰的数组,虽然地址不可改变,但是数组值是可以改变的。
  3. 理论上,反射可以破坏除了枚举的一切东西。
  4. 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 的一些思考。相关推荐

  1. java Hashset去重原理及HashMap key唯一原理

    如下,set中添加重复元素是不可以的,如下 php被添加了2次,但是输出的时候只有一次,那么其去重的原理是什么呢? public class Test {public static void main ...

  2. HashMap key是对象为什么取不到value值

    文章目录 HashMap key是对象为什么取不到value值 场景重现 结果办法 验证 补充 HashMap key是对象为什么取不到value值 场景重现 Product类代码如下 public ...

  3. //身份证改名字问题选择HashMap,key对应vaule

    // 在对集合中元素遍历删除时不要使用集合本事的remove方法,除非是单个移除: // 否则任何时候建议使用迭代器(Iterator)本身的remove方法对元素进行删除 // 注意事项:使用迭代器 ...

  4. python操作string类型的key的代码

    操作环境: ubuntu16.04 python2.7 #-*- encoding:utf-8 -*- import sys reload(sys) sys.setdefaultencoding('u ...

  5. hashmap 允许key重复吗_Java HashMap key 可以重复吗?

    Java HashMap key 可以重复吗? Java的HashMap中key是不可以重复的,如果重复添加的话,HashMap会自动覆盖key一样的数据,保证一个key对应一个value,使用时只要 ...

  6. 为什么 HashMap 常用 String 对象作 key

    偶然的一次机会看到了这个题目,有一个网上的朋友说在面试的时候面到了这道题目,没有能给出解释.这里就谈一谈自己的理解. 在<Java 编程思想>中有这么一句话:设计 hashCode() 时 ...

  7. ArrayList ,LinkedList,Vector,StringBuilder,StringBuffer ,String,HashMap,LinkedHashMap,TreeMap

    ArrayList ,LinkedList,Vector 区别和联系 从上面的类层次结构图中,我们可以发现他们都实现了List接口,它们使用起来非常相似.区别主要在于它们各自的实现,不同的实现导致了不 ...

  8. 由String.equals()方法引起的一系列思考

    2019独角兽企业重金招聘Python工程师标准>>> 废话不多说直接贴String.euqals方法代码 public boolean equals(Object anObject ...

  9. com.netflix.hystrix.exception.HystrixRuntimeException: 类名#方法名(String,String) failed错误引起的一连串思考

    这个错误是在看网上的视频资料学习时产生的,本来以为只是简单的远程调用方法错误,在找错误的过程中发现了不只是这个错误 首先 对于该错误本身是因为远程调用出错,我在认真检查了代码之后发现远程调用代码并没有 ...

最新文章

  1. php 云片网对接,php调用云片网接口发送短信的实现方法
  2. linux版视频转换软件,居家旅行必备的Linux视频转换工具
  3. IOS学习之 网络编程(10)--简单介绍ASI框架的使用
  4. tms570 can 接收大量数据_超全!嵌入式必懂的CAN总线一文讲通了
  5. html5添加渐变边框效果,《CSS3揭秘》上(边框,投影,渐变,条纹效果,蚂蚁行军)...
  6. 服务器之Apache和Tomcat和Nginx的理解和对比
  7. 电脑键盘上每个键的作用_键盘F键有什么作用 键盘F键作用介绍【详解】
  8. oracle ora-01476: 除数为 0,Oracle常见错误:ORA-01403 的根本原因和解决方案
  9. InsecureRequestWarning: Unverified HTTPS request is being made.解决方法
  10. 【CCCC】L3-022 地铁一日游 (30分),floyd+大模拟
  11. centen os7 安装并配置Nexus3.9.0
  12. mysql中根据经纬度求距离_mysql、java中根据经纬度计算距离
  13. 报文学习四(LLDP协议)
  14. 微信小程序开发者工具构建npm
  15. ggplot绘图之基本语法
  16. 派森学python_2019 年 1月 26 日 随笔档案 - 派森学python - 博客园
  17. 案例2:随机森林来填补缺失值
  18. html 萤火虫特效,jquery萤火虫飞舞动画特效插件
  19. 2.22 ACM模拟赛总结
  20. 《4DenoiseNet: Adverse Weather Denoising from Adjacent Point Clouds》

热门文章

  1. Qt5--学习笔记-+openCV2-客户端、服务端回环视频显示
  2. “神似充气娃娃”的人形机器人,made in China
  3. [WebGL入门]二十六,纹理绘图
  4. python之excel处理画图
  5. sift特征检测与匹配
  6. 城市交通的5D模式 | 不同尺度下研究的城市交通
  7. 荣欣Linux运维+Oracle DBA实战训练
  8. boost之内存管理
  9. 元宇宙将如何影响我们的投资、就业和生活方式?
  10. php时间戳 中文,PHP时间戳-WEB资讯专栏-DMOZ中文网站分类目录-免费收录各类优秀网站的中文网站目录....