0

我有一个哈希图,它的键是我的内部类“键”的对象。

我的问题是,当我使用 get(key) 时,它永远不会回馈任何东西。由于 get 与 equals 一起工作,我已经在我的 Key 类中覆盖了 equals,所以它应该适用于 get 方法,但显然它没有。

有什么建议么?

代码:

public class Infrastruktur 
{
    private Zuechter online;
    private HashMap<Key,Zuechter> zuechter;

    Infrastruktur()
    {
        zuechter = new HashMap<Key,Zuechter>();
    }

    }

    public void login(String name, String passwort) 
    {
        Key hashMapKey = new Key(name, passwort);
        if(this.zuechter.get(hashMapKey) != null)
            this.online = this.zuechter.get(hashMapKey);
    }

    public void register(String name, String passwort)
    {
        if(name != null && passwort != null)
        {
            this.zuechter.put(new Key(name,passwort),new Zuechter());
            login(name, passwort);
        }
    }

    public void logOut()
    {
        this.online = null;
    }

    public Zuechter getOnline() {
        return this.online;
    }

    private class Key 
    {
        String name;
        String passwort;

        Key(String name, String passwort) 
        {
            this.name = name;
            this.passwort = passwort;
        }

        @Override
        public boolean equals(Object o)
        {
            if (o == null) return false;
            if (o == this) return true;
            if (!(o instanceof Key)) return false;
            Key key = (Key)o;
            if(this.name.equals(key.name) && this.passwort.equals(key.passwort)) return true;
            return false;
        }
    }

    /* Testing */
    public static void main(String[] args)
    {
        Infrastruktur inf = new Infrastruktur();
        inf.register("Jakob", "passwort");
        inf.logOut();
        inf.login("Jakob", "passwort");
        System.out.println(inf.getOnline().test());
    }
}

如果我运行该类,这是我得到的输出:

not found
not found
Exception in thread "main" java.lang.NullPointerException
        at Infrastruktur.main(Infrastruktur.java:105)
4

3 回答 3

2

您还应该hashCode()为您的Key班级实施。一个示例实现可能是:

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + name.hashCode();
    result = prime * result + passwort.hashCode();
    return result;
}
于 2013-10-17T16:02:54.157 回答
2

使用 Eclipse 生成hashCode您的类的方法。在任何Map情况下,Java 都会对键值进行哈希处理以允许 0(1) 读取访问。

如果找到,它只是散列以跳转到参考。所有 Java IDE 都有一个Generate hashCode and equals选项。一个简单的例子,null省略了检查。

@Override
  public int hashCode() {
    int hash = 3;
    hash = 7 * hash + this.name.hashCode();
    hash = 7 * hash + this.passwort.hashCode();
    return hash;
  }
于 2013-10-17T16:04:23.593 回答
1

您必须在覆盖 equals() 的每个类中覆盖 hashCode()。不这样做将导致违反 Object.hashCode() 的一般约定,这将阻止您的类与所有基于哈希的集合(包括 HashMap、HashSet 和 Hashtable)一起正常运行。

来自 Effective Java,作者 Joshua Bloch

tl; dr要么手动生成 hashCode(),

@Override
  public int hashCode() {
    int hash = 31;
    hash = 29 * hash + Objects.hashCode(name);
    hash = 29 * hash + Objects.hashCode(passwort);
    return hash;
  }

使用 IDE hashCode 生成,或者只使用泛型(虽然速度较慢)

@Override
  public int hashCode() {
    return Objects.hash( name, passwort );
  }

...您甚至可以使用反射为任何类编写通用 hashCode() (非常慢,但作为占位符很好)

顺便说一句,在 hashCode() 中省略对具有 null 作为有效字段值的可变或不可变对象的 null 检查是将错误引入代码的最简单方法之一——这正是需要显式检查或 Objects.hashCode() 的原因。

于 2013-10-17T16:11:50.937 回答