HashMap 的 containsKey 方式未按预期运行
今天我正在做一些寻路,当我不得不使用 contains()
来查找一个类 Coord
是否在另一个 keySet()
坐标
.我发现当我使用预制方法 containsKey()
时,它根本无法按我的意愿工作.我做了一个测试以了解发生了什么,结果如下:
Today I was doing some pathfinding when I had to use contains()
to find if a class Coord
was in an other keySet()
of Coord
.
I found that when I used to premade method containsKey()
, it was simply not working as I wanted. I made a test to find out what is happening and here it is:
HashMap<Coord, Coord> test = new HashMap<Coord, Coord>();
test.put(new Coord(3, 3), new Coord(0, 0));
System.out.println("HashMap test for containsKey : " + test.containsKey(new Coord(3, 3)));
boolean containsKey = false;
for(Coord a : test.keySet())
{
if(a.equals(new Coord(3, 3)))
{
containsKey = true;
}
}
System.out.println("My test for containsKey : "+containsKey);
令人惊讶的是,这是我发现的:
And surprisingly, here is what I found :
HashMap test for containsKey : false
My test for containsKey : true
我只是想知道发生了什么以及为什么.
I just wanted to know what is happening and why.
另外,这里是 Coord
类:
public class Coord
{
public float x, y;
public Coord(float a, float b)
{
this.x = a;
this.y = b;
}
@Override
public boolean equals(Object b)
{
if(b instanceof Coord)
{
Coord casted = (Coord) b;
return casted.x == x && casted.y == y;
}
return false;
}
}
推荐答案
HashMap
s 通过哈希码查找对象.合同的一部分是密钥类必须覆盖 hashCode()
以及 equals()
.单独对象的默认哈希码不相等,因此 get
找不到该对象.相反,当您遍历所有条目时,不使用哈希码,因此仅调用 equals
并找到对象.
HashMap
s find objects by their hash code. Part of the contract is that the key class must override hashCode()
as well as equals()
. The default hash codes for separate objects aren't equal, so the object isn't found by get
. In contrast, when you loop over all entries, the hash code isn't used, so only equals
is called, and the object is found.
要使用 get
找到它,请覆盖 Coord
中的 hashCode
.
To find it using get
, override hashCode
in Coord
.
无论何时重写 equals
,重写 hashCode
总是好的,反之亦然.
It is always good to override hashCode
whenever you override equals
, and vice versa.
相关文章