HashMap的key的问题

shuwei003 2011-12-26 08:45:09

import java.util.HashMap;
import java.util.Map;

class Dog{
public String name;
public Dog(String name){
this.name = name;
}
public boolean equals(Object o){
if((o instanceof Dog) && (((Dog)o).name == name)){
return true;
}else{
return false;
}
}
public int hashCode(){
return name.length();
}
public String toString(){
return name;
}
}

public class Test111226{
public static void main(String[] args) {
Map<Object, Object> m = new HashMap<Object, Object>();
Dog d1 = new Dog("clover");
m.put(d1, "DDDDOG");
System.out.println(m.get(d1));
d1.name = "magnolia";
for(Object o: m.keySet()){
System.out.println(o.hashCode());
System.out.println(o.toString());
}
System.out.println("================");
System.out.println(d1.hashCode());
System.out.println(d1.toString());
System.out.println("----------------");
System.out.println(m.get(d1));

}
}


输出:
DDDDOG
8
magnolia
================
8
magnolia
----------------
null

请问:为什么第一次m.get(d1)的时候能返回"DDDDOG",而将d1.name修改后就返回了null(修改d1的name后,可以看到map中的key的hashCode和name也跟着变了,hashCode和equals仍然相同,为什么get不到呢?)
...全文
146 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
逆乾坤 2011-12-26
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 huntor 的回复:]

Map中请使用 不变的值作为key,不要使用可变的
[/Quote]请教一下,为什么呢?不是只要hashCode一样就行了么?
shuwei003 2011-12-26
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]
楼主请仔细看你的代码

Dog d1 = new Dog("clover");

此时的hashcode()是6 而且你前后两次打印出来的hashcode()都是改变过后的。。细心一点哇
[/Quote]
你没明白我问的是什么,我就是想测试改变之后,key的hashCode和我要取出的对象的hashCode是否一样,问的就是hashCode一样,equals返回也为true,为什么取不到,而返回null。
huntor 2011-12-26
  • 打赏
  • 举报
回复
Map中请使用 不变的值作为key,不要使用可变的
逆乾坤 2011-12-26
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]

楼主请仔细看你的代码

Dog d1 = new Dog("clover");

此时的hashcode()是6 而且你前后两次打印出来的hashcode()都是改变过后的。。细心一点哇
[/Quote]
的确是楼主粗心大意了,
。。。我也跟着粗心了,还测试了半天。。。大早晨就这么晕啊~~~
逆乾坤 2011-12-26
  • 打赏
  • 举报
回复

import java.util.HashMap;
import java.util.Map;

class Dog{
public String name;
public Dog(String name){
this.name = name;
}
public boolean equals(Object o){
if((o instanceof Dog) && (((Dog)o).name == name)){
return true;
}else{
return false;
}
}
public int hashCode(){
return name.length();
}
public String toString(){
return name;
}
}

public class Test111226{
public static void main(String[] args) {
Map<Object, Object> m = new HashMap<Object, Object>();
Dog d1 = new Dog("clover");
m.put(d1, "DDDDOG");
System.out.println(m.get(d1));
//d1.name="123456";//输出DDDDOG
d1.name="1234567";//输出null,因为hashCode改变了。。。。
for(Object o: m.keySet()){
System.out.println(o.hashCode());
System.out.println(o.toString());
}
System.out.println("================");
System.out.println(d1.hashCode());
System.out.println(d1.toString());
System.out.println("----------------");
System.out.println(m.get(d1));

}
}
朝花夕拾 2011-12-26
  • 打赏
  • 举报
回复
楼主请仔细看你的代码

Dog d1 = new Dog("clover");

此时的hashcode()是6 而且你前后两次打印出来的hashcode()都是改变过后的。。细心一点哇
shuwei003 2011-12-26
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
hashcode相同的两个对象,不一定equals
但是两个equals的对象, hashcode一定相同。 楼主现在明白了吗??
[/Quote]
关键是两个对象的hashCode和equals都相同
朝花夕拾 2011-12-26
  • 打赏
  • 举报
回复
而且按你的hashcode()方法来算, 一开始hashcode()是6 后面改变以后hashcode()是8


两者连hashcode()都不一定,又怎么能是同一个对象列?
shuwei003 2011-12-26
  • 打赏
  • 举报
回复
是不是说:虽然d1.name = "magnolia";
改变了m中那个key的值,但是并没有重新放入,所以存储的位置没有变,但是因为名字改变了,equals判断的时候会调用name,所以equals被影响了?
朝花夕拾 2011-12-26
  • 打赏
  • 举报
回复
hashcode相同的两个对象,不一定equals
但是两个equals的对象, hashcode一定相同。 楼主现在明白了吗??

Flycutter 2011-12-26
  • 打赏
  • 举报
回复
hash之所以称为hash就是因为存储的时候是根据hashCode确定存储的位置的。开始的时候hashCode是6,根据这个映射到一个存储位置;之后你更改了对象的属性,影响到了hashCode的计算,变成了8,现在系统根据8来映射到了另一个存储位置,然后使用equals函数判断这个位置的对象和要get的对象是否相等,相等的话就返回,否则返回null。
keySet返回key的集合,遍历输出的话是肯定没问题的了。

62,615

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧