Java HashMap.containsKey(键)找不到键,使用自定义类作为键类型

Java HashMap.containsKey(键)找不到键,使用自定义类作为键类型,java,dictionary,hashmap,equals,Java,Dictionary,Hashmap,Equals,TL;DR:我用自己的“Pair”类对象创建了一个hashmap对象,用作键。当我使用hashmap.containsKey(Pair)时,它找不到密钥 我有一个名为Pair的类,代码如下所示。它应该是两个物体的容器。第一个对象可以是任何类型,而第二个对象必须是整数。这不是一个很好的设计,但是我用这种方式编码它,这样我就可以在我的程序中为其他目的重用这个类 import java.util.ArrayList; public class Pair<L> { private

TL;DR:我用自己的“Pair”类对象创建了一个hashmap对象,用作键。当我使用hashmap.containsKey(Pair)时,它找不到密钥

我有一个名为Pair的类,代码如下所示。它应该是两个物体的容器。第一个对象可以是任何类型,而第二个对象必须是整数。这不是一个很好的设计,但是我用这种方式编码它,这样我就可以在我的程序中为其他目的重用这个类

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;
    }
}
它的计算结果为true,即使我知道密钥在其中,正如我通过调试检查的那样。


如果有人能帮你弄清楚为什么hashmap不能识别这些键,我们将不胜感激。也许我的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():


方法
containsKey(Object)
java.util.HashMap
中使用
java.util.HashMap.getEntry(Object)
调用
hashCode()
获取键的hashCode并使用它检索对象。您需要重写
java.lang.Object.hashCode()
,以使代码正常工作。

您实现了hashCode吗?您实现了
equals()
?您可能还需要将equals方法与默认对象equals方法(对象o)参数vs(对p)的方法对齐,有关记录,请参阅,您也没有实现
toString()
。重写方法时,应养成始终使用
@Override
注释的习惯。您没有重写
equals
hashCode
,也没有重写
toString
。使用
@Override
并遵循Java命名约定将对您有所帮助。感谢您的详细回复。这个解决方案的问题是,在某些情况下,我使用Pair类来保存(int,int)和(Pair,int)。我认为我很有效,但看看它给了我什么,哈哈,我想你还不够。我意识到我不需要更改/添加类,因为我只在成对(int,int)的实例中使用equals()函数。真正起作用的是你的hashCode函数,我现在要去看看它到底做了什么。
if (!costSoFar.containsKey(next))
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;
}
public int hashCode() {
    return this.getLeft() * 31 + this.getRight();
}