2017-03-23 62 views
-1

TL; DR:我用自己的“Pair”类对象制作了一个hashmap对象,用作Keys。当我使用hashmap.containsKey(Pair)时,它无法找到密钥。HashMap.containsKey(key)未能找到密钥,将自定义类用作密钥类型

我有一个叫做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; 
    } 
} 

我存储对作为钥匙,一个HashMap是这样的:

Map<Pair, Integer> costSoFar = new HashMap<Pair, Integer>(); 
costSoFar.put(sLocale, 0); 

当我运行下面的线,这是说,如果关键是没有HashMap的:

if (!costSoFar.containsKey(next)) 

它的计算结果为true,即使我知道钥匙在那里,因为我通过调试进行检查。 The Key is Pair(4,1) And the Key I'm looking for is Pair(4,1)

如果任何人都可以帮忙清理为什么hashmap不能识别密钥,那将是非常感谢。也许我的平等方法不符合要求?

+1

你实现了hashCode吗? – muzzlator

+2

你实现了'equals()'吗? –

+0

此外,您可能需要将您的equals方法与默认的Object equals方法(Object o)参数vs(Pair p)的方法对齐,请参阅http://tutorials.jenkov.com/java-collections/hashcode-equals.html – muzzlator

回答

1

为什么你使用泛型如果L似乎也是int?在java.util.HashMap

public int hashCode() { 
    return this.getLeft() * 31 + this.getRight(); 
} 
+0

感谢您的详细回复。这个解决方案的问题是,在某些情况下,我使用Pair类来保存(int,int)和(Pair,int)。 –

+0

我以为我很高效,但看看它是从哪里得到的,哈哈 –

+0

哇,我想不起你够了。我意识到我不需要改变/添加类,因为我只在对(int,int)的实例中使用equals()函数。这是你的hashCode函数真的做到了这一点,我不知道它究竟做了什么。 –

0

方法containsKey(Object)使用的呼叫hashCode()java.util.HashMap.getEntry(Object)获得哈希码密钥,并用它来:

更换你等于:

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()回顾对象。您需要覆盖java.lang.Object.hashCode()以使您的代码正常工作。

相关问题