2011-11-02 2 views
0

내가이 일 현장 더블 [] _myField 그것의 해시 코드를 가진 개체는자바 대해서 Arrays.hashCode() 이상한 behaivor

public int hashCode() { 
    final int prime = 31; 
    int result = 1; 
    result = prime * result + Arrays.hashCode(_myField); 
    return result; 
} 

그러나입니다 이상한 행동 다음 문이 true이면 내가 그 위 생각할 수

for (Map.Entry<MyObject, String> entry: _myMap.entrySet()) 
    { 
     if (entry.getValue() != _myMap.get(entry.getKey())) 
     { 
       System.out.println("found the problem the value is null"); 

     } 

    } 

유일한 이유는 내가 키에 대해 다른 해시 코드를 얻을 수 있다는 것입니다.

실제로 모든 경우에 1을 반환하도록 hashcode 함수를 변경했습니다. 효율적이지는 않지만 디버깅에 좋으며 실제로 IF 문은 항상 거짓입니다.

Arrays.hashcode()의 문제점은 무엇입니까?

Pls note (일부 의견을 읽은 후) : 1) IF 문에서! =의 사용법은 실제로 참조를 비교하지만 위의 경우에는 동일해야합니다. 어쨌든 괴괴 망측 한 것은 오른쪽이 NULL을 돌려 준다는 것입니다. 2) 게시 동등 함수. 물론 그것을 구현했습니다. 그러나 그것은 부적절합니다. 디버그에서 코드를 추적하면 해시 코드 만 호출된다는 것을 알 수 있습니다. 그 이유는 아마도 이상한 것일 것이고 반환 된 해시 코드는 원래의 해시 코드와 다릅니다. 이 경우 Map은 일치하는 항목을 찾지 않으므로 Equals를 호출 할 필요가 없습니다.

+7

MyObject.equals() 구현을 게시 할 수도 있습니까? –

+0

나는 그것이 부적절 할 수있다. 디버그 모드에서 추적 할 때 해시 코드 함수가 호출되어 원본과 다른 해시 코드를 생성했기 때문입니다. 자바 맵 구현이 equals를 호출하지 않는다는 것을 감안할 때. 꼭 필요한 것은 아니었다. – Dudi

+2

흥미 롭습니다! 문제를 스스로 재현하기에 충분한 코드를 게시 할 수 있습니까? –

답변

5

배열이지도에있는 동안 변경되고 있습니까? 그것은 결과의 결과를 바꿀 것이기 때문입니다.

+1

+1. 심지어 변경되지도 않았으므로 HashMap 키 또는 HashSet에서 바뀔 수있는 해시 코드를 사용하여 무언가를 사용하는 것은 좋지 않습니다. 대답에서 볼 수 있듯이 –

+0

은 배열이 변경되었습니다. – Dudi

2

hashCode를 구현하는 것만으로는 충분하지 않습니다. equals 객체를 구현해야합니다. 사실 객체의 hashCode를 구현할 때마다 equals도 구현해야합니다. 그 2 명은 함께 일합니다.

개체에 equals를 구현하고 equals가 2 개의 개체에 해당 할 때마다 해시 코드도 일치해야합니다.

+4

! = 개체 참조를 비교하고 같음을 호출하지 않습니다 – Gandalf

+0

정말요? 나는 이것을 몰랐다. – anio

+3

@ 간달프 :이 문제와 관련이 없습니다. equals와 hashCode가 올바르게 구현되고있는 경우, 엔트리로부터 취득한 값은 get 메소드로 취득한 값과 동일하지 않으면 안됩니다. –

0

깨끗한 슬레이트에서 문제를 재현하려고 시도하면 재현 할 수 없음이 드러났습니다.

따라서 더 많은 조사를 통해 문제가 인 것으로 밝혀졌습니다. 해시에 사용 된 _myField가 개체가지도에 저장되는 동안 변경되었습니다. 예상대로 맵이 손상되었습니다.

잘못된 질문에 답하려고 한 사람들이 시간 낭비해서 죄송합니다.