HashMap.containsKey(key) 找不到密钥,使用自定义 class 作为密钥类型
HashMap.containsKey(key) failing to find key, with custom class used as key type
TL;DR:我用我自己的 "Pair" class 对象创建了一个 hashmap 对象用作键。当我使用 hashmap.containsKey(Pair) 时,找不到密钥。
我有一个名为 Pair 的 class,代码如下所示。它应该是两个物体的容器。第一个对象可以是任何类型,而第二个对象必须是整数。这不是很好的设计,但我以这种方式编码,因此我可以在我的程序中将 class 用于其他目的。
import java.util.ArrayList;
public class Pair<L> {
private L left;
private int right;
public Pair(L left, int right) {
this.left = left;
this.right = right;
}
public L getLeft() { return left; }
public int getRight() { return right; }
public void ToString() {
System.out.println(left + "," + right);
}
public boolean equals(Pair p) {
return (this.getLeft().equals(p.getLeft()) && this.getRight() == p.getRight());
}
public ArrayList<Pair> neighbors(int rowLimit, int ColumnLimit) {
ArrayList<Pair> neighbors = new ArrayList<Pair>();
Pair neighborL;
Pair neighborR;
Pair neighborU;
Pair neighborD;
if (((int)this.left-1 >= 0)) {
neighborU = new Pair((int)this.left-1, this.right);
// neighborU.ToString();
neighbors.add(neighborU);
}
if ((int)this.left+1 < rowLimit) {
neighborD = new Pair((int)this.left+1, this.right);
// neighborD.ToString();
neighbors.add(neighborD);
}
if ((int)this.right-1 >= 0) {
neighborL = new Pair((int)this.left, this.right-1);
// neighborL.ToString();
neighbors.add(neighborL);
}
if ((int)this.right+1 < ColumnLimit) {
neighborR = new Pair((int)this.left, this.right+1);
// neighborR.ToString();
neighbors.add(neighborR);
}
return neighbors;
}
}
我将 Pairs 作为键存储在哈希图中,如下所示:
Map<Pair, Integer> costSoFar = new HashMap<Pair, Integer>();
costSoFar.put(sLocale, 0);
当我运行下面一行,也就是说,如果key不在hashmap中:
if (!costSoFar.containsKey(next))
它的计算结果为真,即使我知道密钥就在那里,正如我通过调试检查的那样。
如果有人能帮助弄清楚散列图无法识别密钥的原因,我们将不胜感激。也许我的 equals 方法不符合要求?
如果 L 看起来也是 int,为什么还要使用泛型?
替换你的等号:
public boolean equals(Object o) {
if (o instanceof Pair){
Pair p = (Pair)o;
return (this.getLeft().equals(p.getLeft()) && this.getRight() == p.getRight());
}
return false;
}
并实施 int hashCode():
public int hashCode() {
return this.getLeft() * 31 + this.getRight();
}
java.util.HashMap
中的方法containsKey(Object)
使用调用hashCode()
的java.util.HashMap.getEntry(Object)
获取Key的hashCode并用它来检索对象。您需要覆盖 java.lang.Object.hashCode()
以使您的代码正常工作。
TL;DR:我用我自己的 "Pair" class 对象创建了一个 hashmap 对象用作键。当我使用 hashmap.containsKey(Pair) 时,找不到密钥。
我有一个名为 Pair 的 class,代码如下所示。它应该是两个物体的容器。第一个对象可以是任何类型,而第二个对象必须是整数。这不是很好的设计,但我以这种方式编码,因此我可以在我的程序中将 class 用于其他目的。
import java.util.ArrayList;
public class Pair<L> {
private L left;
private int right;
public Pair(L left, int right) {
this.left = left;
this.right = right;
}
public L getLeft() { return left; }
public int getRight() { return right; }
public void ToString() {
System.out.println(left + "," + right);
}
public boolean equals(Pair p) {
return (this.getLeft().equals(p.getLeft()) && this.getRight() == p.getRight());
}
public ArrayList<Pair> neighbors(int rowLimit, int ColumnLimit) {
ArrayList<Pair> neighbors = new ArrayList<Pair>();
Pair neighborL;
Pair neighborR;
Pair neighborU;
Pair neighborD;
if (((int)this.left-1 >= 0)) {
neighborU = new Pair((int)this.left-1, this.right);
// neighborU.ToString();
neighbors.add(neighborU);
}
if ((int)this.left+1 < rowLimit) {
neighborD = new Pair((int)this.left+1, this.right);
// neighborD.ToString();
neighbors.add(neighborD);
}
if ((int)this.right-1 >= 0) {
neighborL = new Pair((int)this.left, this.right-1);
// neighborL.ToString();
neighbors.add(neighborL);
}
if ((int)this.right+1 < ColumnLimit) {
neighborR = new Pair((int)this.left, this.right+1);
// neighborR.ToString();
neighbors.add(neighborR);
}
return neighbors;
}
}
我将 Pairs 作为键存储在哈希图中,如下所示:
Map<Pair, Integer> costSoFar = new HashMap<Pair, Integer>();
costSoFar.put(sLocale, 0);
当我运行下面一行,也就是说,如果key不在hashmap中:
if (!costSoFar.containsKey(next))
它的计算结果为真,即使我知道密钥就在那里,正如我通过调试检查的那样。
如果有人能帮助弄清楚散列图无法识别密钥的原因,我们将不胜感激。也许我的 equals 方法不符合要求?
如果 L 看起来也是 int,为什么还要使用泛型?
替换你的等号:
public boolean equals(Object o) {
if (o instanceof Pair){
Pair p = (Pair)o;
return (this.getLeft().equals(p.getLeft()) && this.getRight() == p.getRight());
}
return false;
}
并实施 int hashCode():
public int hashCode() {
return this.getLeft() * 31 + this.getRight();
}
java.util.HashMap
中的方法containsKey(Object)
使用调用hashCode()
的java.util.HashMap.getEntry(Object)
获取Key的hashCode并用它来检索对象。您需要覆盖 java.lang.Object.hashCode()
以使您的代码正常工作。