2012-09-17 5 views
1

해시 맵에서 값을 검색 할 때 문제가 있습니다. 아이 다음 A.에게Java - HashMap에서 객체 가져 오기

I 확장 4 개 서브 클래스 중 어느 하나 인

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

다음과 같이 그때 맵에 112의 값을 넣어

HashMap<TRpair,A> aTable = new HashMap<TRpair,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++; 
} 

i는 다음과 같이 값 112를 유지합니다. 하나는 예상 할 것이고 평등 테스트는 예상대로 정확하게 하나의 항목에 대해 true를 인쇄합니다.

그러나, 나는

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

널 (null)을 수행 할 때 출력이 정확히 키를 사용하여지도에서 하나 개의 항목이 실제로 있다는 것을 확인 위의 코드에도 불구하고있다. (

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

등호를) 및 toString()이 아이의 각각의 메소드를 (A 연장)과 T 클래스에서 유사하게 무시하고 : 도움이된다면 다음과 같이

, 클래스 TRpair는 선언 예상 한대로 행동하는 것으로 보입니다.

해시 맵 aTable의 출력 값이 이전에 null이었던 이유는 이전에 해당 키 값이 실제로지도에 있는지 확인할 때였습니까?

많은 감사와 함께,

Froskoy.

+2

'TRpair'에서'hashCode()'메소드를 오버라이드해야할까요? –

+0

왜? equals()가 재정의 된 것으로 충분하지 않습니까? – Froskoy

+1

더 많은 객체가 같은 값 (및 상태)을 가진다면'hashCode()'를 대체하여 동일한 값을 유지해야합니다. 더 많은 Hashable 테이블은 해시로 일관성과 평등을 검사합니다. –

답변

3

해시 모음의 키/요소가 있지만 euqals가 재정의 된 경우 hashCode()를 재정의합니다.

사용할 수 있습니다.

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

은 BTW : Integer r하지 int r 더 의미가있는 경우 사용에 null 될 수 있음을 사용자 코드에서 나타납니다. 동일한 오브젝트가 동일한 해시를 가지고 있어야하는 hashCode 메소드의 범용 규약을 유지하기 위해,이 메소드를 오버라이드 (override)하는 경우는, hashCode 메소드를 오버라이드 (override) 해 Object.equals()

주에서

코드.

+0

감사합니다. 31이 임의적 소수이기 때문에 단순히 선택 되었습니까? 아니면 또 다른 이유가 있습니까? – Froskoy

+0

다소 임의적이지만 일반적으로 사용되는 소수입니다. 예 : String.hashCode()는 그것을 사용합니다. –

+0

@Froskoy, 원하는 소수를 사용할 수 있습니다. –

1

IIRC의 해시 맵은 hashCode()가 아니라 평등에 의해보고, 당신이 해시 코드를 구현되지 않았기 때문에 당신은 개체 포인터 평등과 일치하는 기본 구현을 사용 - 는 "계정에 T 소요 적절한 해시 함수를 구현해야 "매개 변수 및 정수 (또는하지 않음)

hashCode() 및 equals()는 일관성이 있지만 구조적으로 필요하지 않은 것이 좋습니다.