2012-09-17 120 views
1

從哈希映射中檢索值時遇到問題。 HashMap中聲明如下:Java - 從哈希映射檢索對象

HashMap<TRpair,A> aTable = new HashMap<TRpair,A>(); 

我然後把112個的值到圖如下:

aTable.put(new TRpair(new T(<value>),new Integer(<value>)),new Ai()); 

其中,Ai是4子類擴展A.

我然後任一項繼續檢查地圖中的值是什麼,如下:

int i = 0; 
for (Map.Entry<TRpair,A> entry : aTable.entrySet()) { 
    System.out.println(entry.getKey().toString() + " " + entry.getValue().toString()); 
    System.out.println(entry.getKey().equals(new TRpair(new T("!"),new Integer(10)))); 
    i++; 
} 

我在最後保持值112,如下人們會期待和平等測試打印正確的一個條目,如預期。

然而,當我做

System.out.println(aTable.get(new TRpair(new T("!"), new Integer(10)))); 

空輸出,儘管上面的代碼片段證實了確實有在地圖上一個條目與正是這種關鍵。

如果有幫助,類TRpair聲明如下:

public class TRpair { 
    private final T t; 
    private final Integer r; 

    protected TRpair(Integer r1, T t1) { 
     terminal = t1; 
     row = r1; 
    } 

    protected TRpair(T t1, Integer r1) { 
     t = t1; 
     r = r1; 
    } 

    @Override 
    public boolean equals(Object o) { 
     TRpair p = (TRpair)o; 
     return (p.t.equals(t)) && (p.r.equals(r)); 
    } 

    @Override 
    public String toString() { 
     StringBuilder sbldr = new StringBuilder(); 
     sbldr.append("("); 
     sbldr.append(t.toString()); 
     sbldr.append(","); 
     sbldr.append(r.toString()); 
     sbldr.append(")"); 
     return sbldr.toString(); 
    } 
} 

了equals()和toString()中的每個的艾的方法(延伸的),並在T類被類似地重寫和似乎表現得像預期的那樣。

爲什麼從hashmap aTable輸出的值爲null,之前已經確認相應鍵的值確實在映射中?

非常感謝,

Froskoy。

+2

您需要重寫'TRpair'中的'hashCode()'方法,否? –

+0

爲什麼? equals()是否被覆蓋是不夠的? – Froskoy

+1

如果更多對象具有相同的值(和狀態),則需要重寫'hashCode()'以維持相等性。更多Hashable表通過散列檢查一致性和相等性。 –

回答

3

Hash集合的鍵/元素,但是覆蓋hashCode()(如果euqals被覆蓋)。

你可以使用。

public int hashCode() { 
    return t.hashCode() * 31^r.hashCode(); 
} 

BTW:它從你的代碼看起來Integer r不能在其中使用的情況下int r更有意義null

Object.equals()

注意,一般需要重寫每當這個方法被重寫hashCode方法,以維護hashCode方法,其中指出相等的對象必須具有相同的哈希總承包合同碼。

+0

謝謝!選擇31是因爲它是一個任意的素數,還是有另一個原因? – Froskoy

+0

它是一個有點隨意但常用的素數。例如String.hashCode()使用它。 –

+0

@Froskoy,你可以使用你選擇的任何素數。 –

1

IIRC HashMap中查找由hashCode()而不是平等,因爲你沒有實現的哈希碼使用默認的實現是與對象指針平等一致的 - 需要實施適當的散列碼功能,考慮到「T 「參數以及整數(或不是)

hashCode()和equals()是一致的,但如果你知道你在做什麼,它不是必須的。