Map的key是否可重复
我们都知道Map的一大特性是key唯一不可重复,可是真的是这样的吗?
我们来试验一下:

运行结果:

我们可以看到在map里有两个同样的person作为key,打破了map的key不可重复的特性。
我们平时操作map一般不会出现这样的结果,怎样操作会出现上述的现象呢?
1、首先有前提条件,作为key的person必须重写hashCode与equals这两个方法保证我们在改变person的属性之后,该person的hash值发生变化。
2、其次是我们在map中put一个以person对象作为key的元素,然后我们修改该person对象的某一个属性,再次把该person对象作为key值put到map中,就得到了上述结果。
为什么会出现上述的问题呢?
我们要明白map的数据结构以及数据是如何存储到map中的
JDK1.7 HashMap是数组+链表的结构
JDK8之后HashMap是数组+链表+红黑树的结构
tips:当然这里我们就不过多的讨论7与8结构的区别
我们在put一个元素的时候,(其余逻辑省略,这里只关注元素如何定位到数组的桶位置),先拿到key对象的hash值h1,h1无符号右移16位得到h2,
再把h1与h2进行异或运算得到h3,h3与数组的(length-1)进行与运算得到元素在数组上的最终位置

tips:如果数组长度较小的时候(大多数情况下map的长度不大),key产生的hash值如果高位变化较大很大,而地位变化很小时,
如果直接拿key的hash值与上(length-1)很容易产生hash冲突,所以无符号右移16位在异或低16位使得高混乱区域与低混乱区域做一个中和,提高hash高低位的一个随机性,减少hash冲突
上面我们讲述了map是如何把元素放入到数组中的,我们再回到上面的问题,第一次把person作为key放入map之后,修改了person的name属性之后,person的hash值发生变化,从而计算出的
桶位置也随之而改变(大概率会改变,不是绝对的)再次put到map中就得到两个相同key值的map。
那么在生产应用中我们要避免使用类似于person这样的对象作为key值存储在Map中,可以使用Integer、String这样一些不可变的对象来作为key就可以避免上述情况的发生。
插一句题外话,HashSet是无序不可重复的,它其实也存在上面的情况,原因很简单HashSet的底层就是HashMap
附HashSet相关代码截图

Map的key是否可重复的更多相关文章
- Java集合篇六:Map中key值不可重复的测试
package com.test.collection; import java.util.HashMap; import java.util.Map; //Map中key值不可重复的测试 publi ...
- java中key值可以重复的map:IdentityHashMap
在Java中,有一种key值可以重复的map,就是IdentityHashMap.在IdentityHashMap中,判断两个键值k1和 k2相等的条件是 k1 == k2 .在正常的Map 实现(如 ...
- java8 stream初试,map排序,list去重,统计重复元素个数,获取map的key集合和value集合
//定义一个100元素的集合,包含A-Z List<String> list = new LinkedList<>(); for (int i =0;i<100;i++) ...
- C++ map通过key获取value
c++的map中通过key获取value的方法 一般是value =map[key],或者另一种迭代器的方式 1.在map中,由key查找value时,首先要判断map中是否包含key. 2.如果不 ...
- map的key排序
java map的key排序吗 java为数据结构中的映射定义了一个接口java.util.Map,他实现了四个类,分别是:HashMap,HashTable,LinkedHashMapTreeMap ...
- 理解ThreadLocal —— 一个map的key
作用: 当工作于多线程中的对象使用ThreadLocal维护变量时,threadLocal为每个使用该变量的线程分配一个独立的变量副本. 接口方法: protected T initialValue( ...
- Java Map按键(Key)排序和按值(Value)排序
Map排序的方式有很多种,两种比较常用的方式:按键排序(sort by key), 按值排序(sort by value).1.按键排序jdk内置的java.util包下的TreeMap<K,V ...
- Android 对Map按key和value分别排序
一.理论准备 Map是键值对的集合接口,它的实现类主要包括:HashMap,TreeMap,Hashtable以及LinkedHashMap等. TreeMap:基于红黑树(Red-Black tre ...
- Java Map 按Key排序和按Value排序
Map排序的方式有很多种,这里记录下自己总结的两种比较常用的方式:按键排序(sort by key), 按值排序(sort by value). 1.按键排序 jdk内置的java.util包下的Tr ...
随机推荐
- BBS项目分布搭建三(个人站点时间归档补充,实现侧边栏跳转、无线级分类、实现文章详情页展示功能)
BBS项目分布搭建三(个人站点时间归档补充,) 1. 个人站点时间归档 """ settings.py设置最好更改以下: LANGUAGE_CODE = 'zh-hans ...
- 把EI科技 【载谈 Binomial Sum】 用人话说出来
这个科技是用来 \(O(k+\log n)\) 求 \(\sum_{i=0}^n [x^i] f(x)p^i(x) \mod x^{k+1}\) 这个多项式的某些项数的线性组合 不过我只见过求第 $ ...
- 《Unity shader入门精要》复习<第13章 关于NDC坐标和深度/法线纹理>
分为三个地方讲解. NDC(Normalize Device Coordinates)归一化的设备坐标 NDC坐标是世界空间坐标通过MVP变换之后再进行归一化得到的坐标.只需要再一步变换就能得到屏幕空 ...
- VUE3 之 列表动画 - 这个系列的教程通俗易懂,适合新手
1. 概述 老话说的好:可以为别人解决痛点的产品就是好产品. 言归正传,今天我们来聊聊 VUE 的列表动画. 2. 列表动画 2.1 列表中增加和删除元素 <style> .my-ite ...
- Java 反射的用法 有关Class类的解释
package com.imooc.test;public class ClassDemo1 { public static void main(String[] args) { Foo fool = ...
- 报错————Type interface com.ssm.mapper.NewProductMapper is not known to the MapperRegistry.
报错: Exception in thread "main" org.apache.ibatis.binding.BindingException: Type interface ...
- asp.net MVC 事务
使用事务的目的是什么? 保证事务范围内的代码,要么全部执行,要么全不执行,也就是出错回滚. 写在数据库脚本里很好理解,但是用在应用程序层面,没有看到catcha error rallback的代码,心 ...
- Kettle错误记录之couldn't open file XXX
业务背景: 简单的TXT文件入库逻辑 组件: 文件文本输入,表输出 具体BUG: 这里报错是无法打开文件,在我尝试了多个思路后,最终发现了问题所在. 因为使用的txt文件的格式是Unix的,而我的文本 ...
- springboot 踩坑之路之 Configuration Annotation Proessor not found in classpath
1.出现spring boot Configuration Annotation Proessor not found in classpath的提示是在用了@ConfigurationPropert ...
- 对路径“C:\inetpub\wwwroot\Test\Temper\”的访问被拒绝 【已解决】
在IIS7上部署IIS站点时,出现如下错误: 对路径"C:\inetpub\wwwroot\Test\Temper\"的访问被拒绝: 原因是:程序对"C:\inetpub ...