【问题标题】:Java - HashMap cannot use new object as search keyJava - HashMap 不能使用新对象作为搜索键
【发布时间】:2017-12-04 20:46:24
【问题描述】:

我在这里尝试做的是使用 Obj 使用键 Key 填充 HashMap ,当我完成时,我希望根据任何可能的键访问这些值。我编写了以下代码,发生的情况是,虽然第一个节目确实显示了我想要的值,但第二个节目引发了NullPointerException

import java.util.*;

public class My{
public static void main(String[] args){
    Map<Key,Obj> myMap = new HashMap<Key,Obj>();

    Obj ob1 = new Obj("Nick",19);
    Obj ob2 = new Obj("George",17);

    Key key1 = new Key(1,2);
    Key key2 = new Key(2,1);

    myMap.put(key1,ob1);
    myMap.put(key2,ob2);

    myMap.get(key1).show();
    myMap.get(new Key(1,2)).show();

}

我可以说 Java 无法分辨出 new Key(1,2)key1 相等,但我想不出如何克服这个问题。

public class Obj{

    private String name;
    private int age;

    Obj(String name, int age){
        this.name = name;
        this.age = age;
    }

    public void show(){
         System.out.println(name + " " + age);
    }
}

这些是我使用的类

import java.* ;

public class Key{

    public int x,y;

    Key(int x, int y){
        this.x = x;
        this.y = y;
    }

    public boolean equals(Key d){
        if ((this.x == d.x)&&(this.y == d.y)){
            return true;
        }
        else{
            return false;
        }
    }
}

【问题讨论】:

  • 你需要在Key中实现hashCode
  • 同样值得学习的模式是,任何时候看到if (condition) return true; else return false;,都可以用return condition; 替换它——所以你的equals 方法可以是return this.x == d.x &amp;&amp; this.y == d.y;
  • 无论何时覆盖equals,您都应该使用相同的功能覆盖hashCode,正是出于这个原因
  • 此外,您没有覆盖从 Object 继承的 equals 方法 - 参数类型是错误的。
  • @janos equals()

标签: java dictionary hashmap


【解决方案1】:

您在实现Key 时遇到了两个问题。首先,equals' 方法签名是错误的——应该是public boolean equals(Object)。如果您使用了 @Override 注释,这个错误会很容易被注意到。其次,您还应该覆盖hashCode() 方法:

@Override
public boolean equals(Object o) {
    if (o == null || getClass() != o.getClass()) {
        return false;
    }
    Key key = (Key) o;
    return x == key.x && y == key.y;
}

@Override
public int hashCode() {
    return Objects.hash(x, y);
}

【讨论】:

  • 你能向 OP 解释一下这个问题吗?例如为什么hashCode 是必要的,为什么它可以解决问题?这与HashMap 有什么关系?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-30
  • 2022-12-31
相关资源
最近更新 更多