2013-10-17 64 views
0

我有一個hashmap,其中key是我的內部類「Key」的一個對象。hashmaps問題獲取函數

我的問題是,當我使用get(key)時,它永遠不會返回任何東西。由於get可以和equals一起工作,所以我在Key類中覆蓋了equals,所以它應該適用於get方法,但顯然它不適用。

有什麼建議嗎?

CODE:

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()); 
    } 
} 

如果我運行的類,這是輸出I得到:

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

您需要''Key'類的'hashCode()'。 –

+0

as @SotiriosDelimanolis said read - http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode() –

回答

1

你必須在每一個重寫的equals類重載hashCode()()。如果不這樣做將違反Object.hashCode()的一般合約,這會阻止您的類與所有基於散列的集合(包括HashMap,HashSet和Hashtable)一起正常運行。

從有效的Java,由Joshua布洛赫

TL;博士手動生成的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()(非常緩慢但很好佔位符)

btw,省略hashCode()中的空值檢查,將null作爲有效字段值的可變或不可變對象作爲將錯誤引入代碼的最簡單方法之一 - 這正是爲什麼明確檢查或Objects.hashCode()需要。

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; 
} 
+0

我想你的意思是寫'name.hashCode()'和'password.hashCode()'在這裏? – Dirk

+0

@Dirk - 的確是' - ) – Mureinik

+0

Thx!解決了! –

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; 
    } 
+0

Thx!解決了! –