2011-05-14 5 views
6

저는 흥미로운 문제가 생겼습니다. 나는 확실히 HashMap의 오류입니다. 다음 코드를 디버깅을 고려 HashMap은 키가 존재하지 않는다고 말합니다.

System.out.println("getBValues - Given: " + key); 
System.out.println("getBValues - Contains Key: " + AMap.containsKey(key)); 
System.out.println("getBValues - Value: " + AMap.get(key)); 
for(Map.Entry<A,HashSet<B>> entry : AMap.entrySet()) { 
    System.out.println("getBValues(key) - Equal: " + (key.equals(entry.getKey()))); 
    System.out.println("getBValues(key) - HashCode Equal: "+(key.hashCode() == entry.getKey().hashCode())); 
    System.out.println("getBValues(key) - Key: " + entry.getKey()); 
    System.out.println("getBValues(key) - Value: " + entry.getValue()); 
} 

지금이지도에 내가 하나의 키 (채널) 및 값을 삽입 (AMAP는 HashMap의이며, 키는이 메서드에 전달 된 값입니다). 나중에 나는 시도하고 get()으로 다시 값을 얻을 내 경우에는이 출력을 제공이 디버그 코드를 실행 : 당신이 볼 수 있듯이

getBValues - Given: Channel(...) 
getBValues - Contains Key: false <--- Doesnt contain key?! 
getBValues - Value: null <--- Null (bad) 
getBValues(key) - Equal: true <--- Given key and AMap key is equal 
getBValues(key) - HashCode Equal: true 
getBValues(key) - Key: Channel(Same...) 
getBValues(key) - Value: [] <--- Not null (This is the expected result) 

, HashMap의에서 키를 가져 오는 것은 직접 작업 있지만 통해 반복하지 않습니다 정확히 동일한 키를 얻으십시오. 즉, get()으로는 찾을 수 없습니다. 내 질문은이 원인이 무엇입니까? get()은 존재하는 키를 어떻게 찾을 수 없습니까?

이 예제 코드를 제공 하겠지만이 코드는 독립적으로 재현 할 수 없습니다.

무엇이 발생했는지에 대한 제안이 있으십니까?

+3

* "나는 확실히 HashMap의 잘못입니다."*. 나 후에 반복해라. "버그는 ** my ** 코드에 있습니다." - http://programmers.stackexchange.com/questions/1785/what-should-every-programmer-know-about-programming/1842#1842 –

+0

@Stephen HashMap에서 "일부 '기능'이 이 " – TheLQ

답변

4

, 우리는 여전히 배제하지 않은 그의 "효과적인 자바"장에서 올바르게 수행하는 방법을 알려줍니다 불변성. 다음과 같은 경우 :

aMap.put(key, value); 
key.setFieldIncludedInHashCodeAndEquals(25); 

위의 결과가 나타납니다.

는 디버거를 사용하여, 이것을 배제, 중 우리에게 코드의 자세한 내용을 표시하거나의에서 루프에 대한 귀하의 위의 예에서, 또한

System.out.println(aMap.get(entry.getKey())); 

을 추가합니다. 이렇게하면 개체가 올바른 양동이에 있는지 확인할 수 있습니다.

+0

흠 ... 그게 나에게 값을 줬어. hashCode 추가 된 후 변경됩니다 같아요. 코드를 실행할 수있는 것으로 업데이트 할 수 있는지 확인합니다. – TheLQ

+0

그래서지도에 객체를 추가 한 후에 aMap에 키로 저장 한 객체에서 hashCode 또는 equals의 일부인 필드가 변경 되었습니까? – Buhb

+0

지도의 키가 변경되지 않아야하는 이유가 여기에 있습니다. – duffymo

8

키 채널 클래스에서 equals와 hashCode를 제대로 재정의하지 않았을 것입니다. 그것은 그것을 설명 할 것이다.

여호수아 블로흐는 당신이 함께 할 수있는 경우 내가 볼 수있는 3.

http://java.sun.com/developer/Books/effectivejava/Chapter3.pdf

+0

나는 프로젝트 롬복과 함께했다. 심지어 평등에 영향을 미칠 클래스에서 2 개의 HashSet을 제외했다. – TheLQ

+0

나는 Project Lombok이 무엇인지 모른다. 그게 "네, 적절한 equals와 hashCode가 구현되어 있습니다."라는 뜻인지는 알 수 없습니다. 열쇠가 불변 인 경우에 최적입니다. 귀하의 채널에 해당합니까? – duffymo

+1

그의 특정 테스트에서 hashCode는 키와 저장된 키에 대해 동일한 값을 제공합니다. 잘못되거나 올바르게 구현 될 수도 있지만이 경우에는 올바르다. key.equals (entry.key)도 true를 반환합니다. 유일한 남은 원인은 entry.key.equals (key)가 false인지 확인할 수 있습니다. –

관련 문제