【问题标题】:java HashMap containsKey is returning false though key is present尽管存在键,但java HashMap containsKey返回false
【发布时间】:2012-03-05 21:32:02
【问题描述】:

我正在使用 HashMap 数据结构来存储 SqMatrix(方阵),其中键是 MatrixIndex 类型(包含行和列),值是整数类型。

但是当我得到 false 作为“if (mat.containsKey(key))”的输出时,尽管 HashMap 中有相应的键。

主要代码:

public static void main(String[] args) {

    Random generator = new Random();
    int val = 0;
    Types.MatrixIndex key, key1;
    int matSz = (int) Math.floor(Math.sqrt(10));
    Types.SqMatrix mat = new Types().new SqMatrix(matSz); //matSz*matSz elements
    //HashMap<Types.MatrixIndex,Integer> hMap= new HashMap<Types.MatrixIndex,Integer>(10);
    for (int r=0; r<matSz; r++) {
        for (int c=0; c<matSz; c++) {
            if (r<c) {
                val = generator.nextInt(2) > 0? -1 : val;
                key =(new Types()).new MatrixIndex(r, c);
                key1 = (new Types()).new MatrixIndex(c, r);
                mat.put(key, val);
                mat.put(key1, val);
                generator.setSeed(System.currentTimeMillis());
            }
        }
    }

    for (int r=0; r<matSz; r++) {
        val = 0;
        for (int c=0; c<matSz; c++) {
            if (r!=c) {
                key = (new Types()).new MatrixIndex(r, c);
                if (mat.containsKey(key)) {
                    val = val + mat.get(key);
                }

            }
        }
        key1 = (new Types()).new MatrixIndex(r, r);
        mat.put(key1, val);
    }

有人知道为什么 containsKey 虽然存在于 HashMap 中却返回 false 吗?

提前致谢,

索姆纳特

【问题讨论】:

  • stackoverflow.com/questions/1104030/…接受 答案可能会有所帮助,因为我怀疑您还没有为MatrixIndex 类实现equals()hashCode()
  • 我没有任何链接可以接受答案。任何线索如何接受任何回复?

标签: java


【解决方案1】:

我不知道MatrixIndex 是什么,但如果它的哈希码实现没有被覆盖,那么MatrixIndex 的每个实例都有它自己的哈希码,并且被认为是唯一的。因此,您不能传入一个新的 MatrixIndex 实例来进行containsKey() 检查。

如果您想让确切的代码 sn-p 起作用,您需要在 MatrixIndex 类中覆盖 equals()hashcode(),并使其始终为该类创建可重现的唯一值。

如果您以前没有这样做过,请务必阅读有关覆盖这两种方法的内容。快速搜索会带来很多帮助。如果您可以在项目中添加新库,请查看:http://commons.apache.org/lang/api-2.4/org/apache/commons/lang/builder/HashCodeBuilder.html

【讨论】:

  • 感谢您提供链接。会看一看,让我们知道。
【解决方案2】:

您是否(正确地)在 MatrixIndex 类中定义了 equals()hashCode()

【讨论】:

  • 这里是MatrixIndex类的实现: public class MatrixIndex implements Comparable { public int row;公共 int col; //...构造函数、getter、setter等... @Override public int compareTo(MatrixIndex o) throws ClassCastException { //... implementation } public boolean equals(MatrixIndex mI) { if (mI.getrow() = = this.getrow() && mI.getcol() == this.getcol()) 返回真;返回假; } }
  • 我没有添加 hashCode()。这需要什么以及如何实现?
  • @somnathchakrabarti,equals() 的实现肯定是错误的。您必须接受Object 参数到equals。 (而且你还需要实现hashCode。)
  • 是的,但在我的例子中,关键的对象类型是 MatrixIndex。所以我重写了 MatrixIndex 中的 equals 方法,并将 MatrixIndex 作为参数传递,而不是 Object。为什么应该是Object?
  • 您编写的方法不会覆盖Object 中的equals() 方法,因此永远不会被调用。另外,它不遵守equals() 的约定(例如,传递null 将导致NullPointerException)。如果我是你,我会让你的 IDE 为你编写 equals()hashCode() 方法。
【解决方案3】:

要使containsKey() 成功,两个对象(您测试的对象和在 Map 的键中找到的对象)必须具有相同的 hashCode()(对于非空对象)并且 equals() 必须 [对称地] 成功给他们。

containsKey() "当且仅当此映射包含键 k 的映射时返回 true,使得 (key==null ? k==null : key.equals(k))。(可以有最多一个这样的映射。)" (reference)。

【讨论】:

  • 是的,我看过 javadocs,然后才在 MatrixIndex 类中实现了 equals 方法。
【解决方案4】:

很可能您忘记覆盖MatrixIndex.hashCode() 和/或MatrixIndex.equals()。从Object 类继承的默认版本比较对象身份,而不是对象的内容,并且不会执行您可能期望的操作。

【讨论】:

  • Kosmulski 我已经在评论中发布了 equals 实现。但不确定 hashCode 的实现。什么是好的 hashCode 函数?因为我猜这就是 containsKey 仍然返回 false 的原因
  • 我找不到您提到的hashCode() 的代码。然而,最重要的是如果两个对象实例根据equals() 相等,它们也必须返回相同的哈希码(不一定相反)。如果您在MatrixIndex 中有一行和一列,您可以从hashCode() 返回它们的总和或row+N*col,其中N 是一个相对较大的素数。
猜你喜欢
  • 1970-01-01
  • 2012-10-04
  • 1970-01-01
  • 2020-01-19
  • 2018-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-11
相关资源
最近更新 更多