Hashmap 中的 key 值为自定义类型,使用 containsKey 方法无法判断 Key 是否在 Hashmap 中,求教。

2016-01-18 09:55:44 +08:00
 anonymoustian

我在 Java 中用 Twowords 类封装了两个元素,这两个元素作为 Hashmap 的 Key 共同确定了 Hashmap 中的 Value ,但是我在写代码的过程中,需要判断 Twowords 对象是否在 Hashmap 里从而确定是否对 Value 赋值或者对 Value 进行自增操作。
但是我写的代码并不能判断 Hashmap 是否有 Key 值,问题应该出在 new 上,请问有没有好的解决办法?

HashMap<Twowords, Double> transitions = new HashMap<Twowords, Double>();

Twowords tmp = new Twowords(first, second);

if (transitions.containsKey(tmp)){
transitions.put(tmp, transitions.get(tmp) + 1.0);
}
else{
transitions.put(tmp, 1.0);
}

也就是说 if 判断永远为假,请问怎么解决呢? 谢谢!

5242 次点击
所在节点    Java
28 条回复
bigredapple
2016-01-18 09:59:21 +08:00
hashcode
ilaipi
2016-01-18 09:59:51 +08:00
需要在`Twowords`里面重写 `hashcode()`和`equals()`两个方法
zts1993
2016-01-18 10:07:37 +08:00
不够理解 HashMap 的原理 啊。。。
beneo
2016-01-18 10:17:09 +08:00
@ilaipi 说的对
anonymoustian
2016-01-18 10:24:09 +08:00
@ilaipi 您好,我是重写了的。请问这个写的对吗?
public int hashCode(){
return element1.hashCode()+element2.hashCode();
}
public boolean equals(Twowords o){
if(o.hashCode() == this.hashCode()){
return true;
}
return false;
}
anonymoustian
2016-01-18 10:24:33 +08:00
@zts1993 你好,我重载了 hashCode 和 equals 方法的。
public int hashCode(){
return element1.hashCode()+element2.hashCode();
}
public boolean equals(Twowords o){
if(o.hashCode() == this.hashCode()){
return true;
}
return false;
}
fwrq41251
2016-01-18 10:29:54 +08:00
有用 IDE 吗,eclipse 里面按 alt+shift+s 里面有一项 generate hashCode and equals..
otakustay
2016-01-18 10:30:09 +08:00
HashMap<Twowords, Double> transitions = new HashMap<Twowords, Double>();

这句看起来是个局部变量,也就是说每次运行代码都创建一个新的 HashMap ,那每次判断 containsKey 的时候这个 HashMap 都是空的,自然是 false ……

可能你贴出来的代码不全面,所以不好判断原因
ilaipi
2016-01-18 10:35:59 +08:00
@anonymoustian
element1 和 element2 是什么类型?
你的 hashCode 方法,得看你 element 类型的 hashCode 了

equals 方法这么写可能会出问题的。 3+5=4+4=1+7...

你网上搜下 hashCode 和 equals 方法的重写,有很多的例子
anonymoustian
2016-01-18 10:39:26 +08:00
@ilaipi 您好,我把完整代码贴出来了,您能看一下吗?
anonymoustian
2016-01-18 10:39:53 +08:00
@otakustay 您好,我把完整代码贴出来了,您能看一下吗?
zacard
2016-01-18 10:40:10 +08:00
hashcode 和 equals 方法写错了
anonymoustian
2016-01-18 10:41:16 +08:00
@zacard 您看我写的哪里错了?
AccIdent
2016-01-18 10:45:49 +08:00
1. hashcode 和 equals 尽量不要自己写,而且你写的有问题
2. 你的 code 明显不可能有 key 啊, HashMap<Twowords, Double> transitions = new HashMap<Twowords, Double>();//new 的空 hashmap ,后面又没有 put ,能有 key 才有鬼呢

//话说代码没有格式看着难受
Infernalzero
2016-01-18 10:47:24 +08:00
IDE 直接生产下 hashcode 和 equals 方法就行了,你不重写的话就是调用 Object 的了,你每次 new 一个对象当然不等了
ilaipi
2016-01-18 11:01:49 +08:00
@anonymoustian
你的测试类的输出结果是?
anonymoustian
2016-01-18 11:03:59 +08:00
问题解决了。 IDE 生成的 hashcode 和 equals 方法就可以了。谢谢大家!~
hantsy
2016-01-18 11:04:36 +08:00
选择可以 identify 两个对象的一些字段生成相应的 equals 和 hashcode 。
gy911201
2016-01-18 11:55:40 +08:00
问题出在 public boolean equals(Twowords o)上,你实际上没有覆写 equals , 而是重载了它,正确的 equals 只应该传入 Object 类型
wizardforcel
2016-01-18 13:51:11 +08:00
继承自 object 的 hashcode 是按照地址生成的,重新 new 一个当然不成了。

自己覆写 hashcode ,原理就是每个成员(也可以是部用于标识对象的分成员)的 hashcode 进行一定运算,搜一下就知道怎么做了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/251496

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX