如何判断map里面的key 是否map中key可以重复吗

key可以重复的Map集合:IdentityHashMap -
- ITeye博客
博客分类:
IdentityHashMap:key可以重复的Map集合
key允许重复,只要两个对象的地址不相等即可。
class Person {
public Person(String name, int age) {
this.name =
this.age =
public boolean equals(Object obj) {
// 判断地址是否相等
,返回true表示同一对象
if (this == obj) {
// 传递进来的不是本类的对象 ,返回false表示不是同一对象
if (!(obj instanceof Person)) {
// 进行向下转型
Person p = (Person)
if (this.name.equals(p.name) &&this.age == p.age) {
public int hashCode(){
return this.name.hashCode() * this.
public String toString() {
return "姓名:" + this.name + ";年龄:" + this.
Map&Person, String& map = new IdentityHashMap&Person, String&();
map.put(new Person("A", 30), "A1");
map.put(new Person("A", 30), "A2");
map.put(new Person("B", 31), "lisi");
Set&Map.Entry&Person, String&& allSet = map.entrySet();
Iterator&Map.Entry&Person, String&& iter = allSet.iterator();
while (iter.hasNext()) {
Map.Entry&Person, String& me = iter.next();
System.out.println(me.getKey()+ " --& " + me.getValue());
浏览: 68231 次
来自: 北京
很有用,学习了博客访问: 298674
博文数量: 56
博客积分: 492
博客等级: 下士
技术积分: 866
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: C/C++
&&& 首先,不推荐使用[]来判断key是否存在,因为使用操作符[]会向map容器里插入一个元素。
&&&& map的operator[]重载大致是这样一个内容: & & & & data_type& & operator[]( & const & key_type& & k & ) & & & & { & & & & value_type & v(k, & data_type()); & & & & iterator & it & = & insert(v). & & & & return & it-& & & & & }
&&&& 大致是这样,如果没有找到的话就插入一个,然后返回它的second。
&&& 正确的判断方法是使用map的find函数,由于map是一个红黑树,find的时间复杂度是logn,可以接受。
&&& bool i***ist(const String& keyName)&&& {&&&&&&& return ( mRegistryMap.find(keyName) != mRegistryMap.end() );&&& }
阅读(27339) | 评论(5) | 转发(3) |
相关热门文章
给主人留下些什么吧!~~
桔色花朵: 哈哈,和谐的太给力了!.....河蟹无处不在..
桔色花朵: 哈哈,和谐的太给力了!.....河蟹无处不在..
businiaowyf: 我晕 Is Exist&&中间三个字母竟然被和谐了。。.....哈哈,和谐的太给力了!
校长的马夹: find函数真不错!.....我晕 Is Exist&&中间三个字母竟然被和谐了。。
find函数真不错!
请登录后评论。问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
System.out.println("a**"+map.get(a).getClass());System.out.println("a**"+map.get(a));
-------------分割线------------a**class java.util.ArrayLista**[]
以上是控制台打印出来的东西。
map.get(a).toString().equals("");一直是falsemap.get(a)!=null;一直是true
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
如果一个 ArrayList 已经实例化,那肯定不等于 null 了。既然可以执行 toString 方法而不报错,肯定是实例化过的。因为 toString 是顶级父类 Object 的方法,没有实例化的对象怎么可能有这个方法。
ArrayList list = new ArrayList();
System.out.println(list == null);
ArrayList list1 =
System.out.println(list1.toString()); // 空指针
分享到微博?
Hi,欢迎来到 SegmentFault 技术社区!⊙▽⊙ 在这里,你可以提出编程相关的疑惑,关注感兴趣的问题,对认可的回答投赞同票;大家会帮你解决编程的问题,和你探讨技术更新,为你的回答投上赞同票。
明天提醒我
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:HashMap中出现重复的key, 求解释
Person p1 = new Person(xiaoer,1);
Person p2 = new Person(san,4);
Map maps = new HashMap();
maps.put(p1, 1111);
maps.put(p2, 2222);
System.out.println(maps);
maps.put(p2, 333);
System.out.println(maps);
p1.setAge(5);
System.out.println(maps);
maps.put(p1, 333);
System.out.println(maps);
System.out.println(maps.get(p1));
输出结果:
{Person [name=san, age=4]=2222, Person [name=xiaoer, age=1]=1111}
{Person [name=san, age=4]=333, Person [name=xiaoer, age=1]=1111}
{Person [name=san, age=4]=333, Person [name=xiaoer, age=5]=1111}
{Person [name=san, age=4]=333, Person [name=xiaoer, age=5]=1111, Person [name=xiaoer, age=5]=333}
重点关注 红色的 标注。
其中Person类如下:
class Person{
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result +
result = prime * result + ((name == null) ? 0 : name.hashCode());
/* (non-doc)
* @see java.lang.Object#equals(java.lang.Object)
public boolean equals(Object obj) {
if (this == obj)
if (obj == null)
if (getClass() != obj.getClass())
Person other = (Person)
if (age != other.age)
if (name == null) {
if (other.name != null)
} else if (!name.equals(other.name))
/* (non-Javadoc)
* @see java.lang.Object#toString()
public String toString() {
return Person [name= + name + , age= + age + ];
why? 输出的maps 出现了相同的key。
初步 判断 和 HashMap的 hashcode机制有关, 只在第一次 将 元素 add 加入map时,检测元素key的 hash值。 之后我通过外部 手段 更改了对象的值,再将 该对象加入 map,其实 从hashcode来看 已经是一个新的 对象了,故 map认为他们的key 不同。HashMap为了提高校验速度,并不会 将待增的元素 与 map中已有的所有元素 一 一 比较,而只是快速的比较hashcode table 表? 虽然从物理内存上看 他们的确是 同一个对象。
java 这样设计的原理 何在?
这样其实存在不安全性。 譬如 我将一个 hashMap对象 传给了 方法A 去处理,结果A还在处理中的 时候,我把hashMap对象的里面的一个元素的值 给 简介更改了,而A 竟然还不知情。【GoLang笔记】遍历map时的key随机化问题及解决方法
- Go语言中文网 - Golang中文社区
<meta name="author" content="polaris ">
【GoLang笔记】遍历map时的key随机化问题及解决方法
· 15014 次点击 ·
开始浏览 & &
之前的曾分析过,Go的map在底层是用hashmap实现的。由于高效的hash函数肯定不是对key做顺序散列的,所以,与其它语言实现的hashmap类似,在使用Go语言map过程中,key-value的插入顺序与遍历map时key的访问顺序是不相同的。熟悉hashmap的同学对这个情况应该非常清楚。
所以,本文要提到的肯定不是这个,而是一个比较让人惊奇的情况,下面开始说明。
1. 通过range遍历map时,key的顺序被随机化
在golang 1.4版本中,借助关键字range对Go语言的map做遍历访问时,前后两轮遍历访问到的key的顺序居然是被随机化的!
这个现象在其它语言中是很少见的,比如C语言实现hashmap时,通常会用数组(即一段连续的内存空间)来存key,虽然key的分布顺序与插入顺序不一致,但k-v数据填充完毕后,整个hashmap的key的次序是固定的,所以,后续遍历这个hashmap时,每轮遍历访问到的key的顺序是一致的。
但Go语言通过range遍历map时,确实会对map的key顺序做随机化。下面是一段简单的验证程序。
// map_range_rand.go
package main
&#34;fmt&#34;
func main() {
m := make(map[string]string)
m[&#34;hello&#34;] = &#34;echo hello&#34;
m[&#34;world&#34;] = &#34;echo world&#34;
m[&#34;go&#34;] = &#34;echo go&#34;
m[&#34;is&#34;] = &#34;echo is&#34;
m[&#34;cool&#34;] = &#34;echo cool&#34;
for k, v := range m {
fmt.Printf(&#34;k=%v, v=%v\n&#34;, k, v)
}在go v1.4环境中,执行go build map_range_rand.go完成编译后,运行产出的2进制文件,结果如下。
第1次运行输出:
$ ./map_range_rand
k=is, v=echo is
k=cool, v=echo cool
k=hello, v=echo hello
k=world, v=echo world
k=go, v=echo go第2次运行输出:
$ ./map_range_rand
k=go, v=echo go
k=is, v=echo is
k=cool, v=echo cool
k=hello, v=echo hello
k=world, v=echo world第3次运行输出:
$ ./map_range_rand
k=hello, v=echo hello
k=world, v=echo world
k=go, v=echo go
k=is, v=echo is
k=cool, v=echo cool可以很清楚地看到,每次遍历时,key的顺序都是不同的。
后来在golang官方blog的文章中,确认了这个现象确实存在,而且是Go语言的设计者们有意为之,在这篇文章关于Iteration order的说明中提到:
When iterating over a map with a range loop, the iteration order is not specified and is not guaranteed to be the same from one iteration to the next. Since Go 1 the runtime randomizes map iteration order, as programmers relied on the stable iteration
order of the previous implementation.
看起来是因为大家在使用Go的map时,可能会在业务逻辑中依赖map key的稳定遍历顺序,而Go底层实现并不保证这一点。因此,Go语言索性对key次序做随机化,以提醒大家不要依赖range遍历返回的key次序。
奇怪的是,我在golang 1.2环境中编译上面的示例代码后反复运行,输出结果中key的次序是非随机化的。
不过,不管如何,这个默认的次序肯定是不能依赖的。
2. 业务依赖key次序时,如何解决随机化问题
其实Go maps in action一文已经给出了解决方法:
If you require a stable iteration order you must maintain a separate data structure that specifies that order.
可见,需要另外维护一个数据结构来保持有序的key,然后根据有序key来遍历map。
下面是本文对上个例子给出的稳定遍历次序的解决方法。
package main
&#34;fmt&#34;
&#34;sort&#34;
func main() {
m := make(map[string]string)
m[&#34;hello&#34;] = &#34;echo hello&#34;
m[&#34;world&#34;] = &#34;echo world&#34;
m[&#34;go&#34;] = &#34;echo go&#34;
m[&#34;is&#34;] = &#34;echo is&#34;
m[&#34;cool&#34;] = &#34;echo cool&#34;
sorted_keys := make([]string, 0)
for k, _ := range m {
sorted_keys = append(sorted_keys, k)
// sort &#39;string&#39; key in increasing order
sort.Strings(sorted_keys)
for _, k := range sorted_keys {
fmt.Printf(&#34;k=%v, v=%v\n&#34;, k, m[k])
}上面的示例中,通过引入sort对key做排序,然后根据有序的keys遍历map即可保证每次遍历map时的key顺序是固定的。
$ go build map_range_rand.go 可以验证,每次的执行结果中key的次序都是按字典序进行升序排列的:
$ ./map_range_rand
k=cool, v=echo cool
k=go, v=echo go
k=hello, v=echo hello
k=is, v=echo is
k=world, v=echo world
【参考资料】
=========================== EOF ==========================
15014 次点击 &?& 1 赞 &
请尽量让自己的回复能够对别人有帮助
支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
支持 @ 本站用户;支持表情(输入 : 提示),见
图片支持拖拽、截图粘贴等方式上传
记住登录状态
之前的曾分析过,Go的map在底层是用hashmap实现的。由于高效的hash函数肯定不是对key做顺序散列的,所以,与其它语言实现的hashmap类似,在使用Go语言map过程中,key-value的插入顺序与遍历map时key的访问顺序是不相同的。熟悉hashmap的同学对这个情况应该非常清楚。
所以,本文要提到的肯定不是这个,而是一个比较让人惊奇的情况,下面开始说明。
1. 通过range遍历map时,key的顺序被随机化
在golang 1.4版本中,借助关键字range对Go语言的map做遍历访问时,前后两轮遍历访问到的key的顺序居然是被随机化的!
这个现象在其它语言中是很少见的,比如C语言实现hashmap时,通常会用数组(即一段连续的内存空间)来存key,虽然key的分布顺序与插入顺序不一致,但k-v数据填充完毕后,整个hashmap的key的次序是固定的,所以,后续遍历这个hashmap时,每轮遍历访问到的key的顺序是一致的。
但Go语言通过range遍历map时,确实会对map的key顺序做随机化。下面是一段简单的验证程序。
// map_range_rand.go
package main
&#34;fmt&#34;
func main() {
m := make(map[string]string)
m[&#34;hello&#34;] = &#34;echo hello&#34;
m[&#34;world&#34;] = &#34;echo world&#34;
m[&#34;go&#34;] = &#34;echo go&#34;
m[&#34;is&#34;] = &#34;echo is&#34;
m[&#34;cool&#34;] = &#34;echo cool&#34;
for k, v := range m {
fmt.Printf(&#34;k=%v, v=%v\n&#34;, k, v)
}在go v1.4环境中,执行go build map_range_rand.go完成编译后,运行产出的2进制文件,结果如下。
第1次运行输出:
$ ./map_range_rand
k=is, v=echo is
k=cool, v=echo cool
k=hello, v=echo hello
k=world, v=echo world
k=go, v=echo go第2次运行输出:
$ ./map_range_rand
k=go, v=echo go
k=is, v=echo is
k=cool, v=echo cool
k=hello, v=echo hello
k=world, v=echo world第3次运行输出:
$ ./map_range_rand
k=hello, v=echo hello
k=world, v=echo world
k=go, v=echo go
k=is, v=echo is
k=cool, v=echo cool可以很清楚地看到,每次遍历时,key的顺序都是不同的。
后来在golang官方blog的文章中,确认了这个现象确实存在,而且是Go语言的设计者们有意为之,在这篇文章关于Iteration order的说明中提到:
When iterating over a map with a range loop, the iteration order is not specified and is not guaranteed to be the same from one iteration to the next. Since Go 1 the runtime randomizes map iteration order, as programmers relied on the stable iteration
order of the previous implementation.
看起来是因为大家在使用Go的map时,可能会在业务逻辑中依赖map key的稳定遍历顺序,而Go底层实现并不保证这一点。因此,Go语言索性对key次序做随机化,以提醒大家不要依赖range遍历返回的key次序。
奇怪的是,我在golang 1.2环境中编译上面的示例代码后反复运行,输出结果中key的次序是非随机化的。
不过,不管如何,这个默认的次序肯定是不能依赖的。
2. 业务依赖key次序时,如何解决随机化问题
其实Go maps in action一文已经给出了解决方法:
If you require a stable iteration order you must maintain a separate data structure that specifies that order.
可见,需要另外维护一个数据结构来保持有序的key,然后根据有序key来遍历map。
下面是本文对上个例子给出的稳定遍历次序的解决方法。
package main
&#34;fmt&#34;
&#34;sort&#34;
func main() {
m := make(map[string]string)
m[&#34;hello&#34;] = &#34;echo hello&#34;
m[&#34;world&#34;] = &#34;echo world&#34;
m[&#34;go&#34;] = &#34;echo go&#34;
m[&#34;is&#34;] = &#34;echo is&#34;
m[&#34;cool&#34;] = &#34;echo cool&#34;
sorted_keys := make([]string, 0)
for k, _ := range m {
sorted_keys = append(sorted_keys, k)
// sort &#39;string&#39; key in increasing order
sort.Strings(sorted_keys)
for _, k := range sorted_keys {
fmt.Printf(&#34;k=%v, v=%v\n&#34;, k, m[k])
}上面的示例中,通过引入sort对key做排序,然后根据有序的keys遍历map即可保证每次遍历map时的key顺序是固定的。
$ go build map_range_rand.go 可以验证,每次的执行结果中key的次序都是按字典序进行升序排列的:
$ ./map_range_rand
k=cool, v=echo cool
k=go, v=echo go
k=hello, v=echo hello
k=is, v=echo is
k=world, v=echo world
【参考资料】
=========================== EOF ==========================
&最高记录 1364
&2012- Go语言中文网,中国 Golang 社区,致力于构建完善的 Golang 中文社区,Go语言爱好者的学习家园。
Powered by
&o&服务器由
赞助 &·&CDN 由
VERSION: V3.0.0&·&4.382411ms&·&为了更好的体验,本站推荐使用 Chrome 或 Firefox 浏览器
登录和大家一起探讨吧
记住登录状态
还不是会员}

我要回帖

更多关于 java map key重复 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信