2010-06-02 3 views
8

필자는 Comparable compareTo 메서드를 구현하는 "Accumulator"라는 클래스가 있는데이 개체를 HashSet에 넣으려고합니다.Java HashSet은 중복을 허용합니다. 비교할만한 문제가 있습니까?

HashSet에()를 추가하면 내 중단 점을 설정 한 위치와 상관없이 디버거의 compareTo 메소드에 아무런 활동도 표시되지 않습니다. 또한 add()로 끝내면 Set 내에서 여러 개의 복제본을 볼 수 있습니다.

나는 여기서 무엇을 망쳤습니다. 왜 그것이 비교가 아니며, 따라서 속임수를 허용합니까?

감사합니다,
IVR 복수하는

답변

15

무엇이 잘못 되었습니까?

HashSet은 compareTo()이 아니라 hashCode()을 기반으로합니다. TreeSet과 혼동을 줄 수 있습니다. 두 경우 모두 다른 방법과 일치하는 방식으로 equals()도 구현해야합니다.

10

올바르게 hashCode()equals()를 구현해야합니다.

hashCode을 덮어 쓰고 두 개의 동일한 객체가 동일한 해시 코드를 갖도록 클래스의 값을 기반으로 한 숫자를 반환해야합니다.

+0

그렇지 않으면 완전히 잘못되었습니다. – Justin

1

HashSet은 hashCode와 같음을 사용합니다. TreeSet는 Comparable 인터페이스를 사용합니다. 참고 : 해시 코드 또는 같음을 재정의하려면 항상 다른 쪽을 재정의해야합니다.

+1

equals가 오버라이드 (정의가 동일하다면 변경)되는 경우에만 hashCode를 재정의해야합니다. 다른 방법은 반드시 사실 일 필요는 없습니다. hashCode를 변경하여 1을 반환하고 equals 만 남겨 두는 것은 매우 합법적입니다. –

2

hashCode가 2 개의 객체에 대해 다른 값을 반환하면 equal은 사용되지 않습니다. BTW, compareTo와는 컬렉션을 해싱과는 아무 :)하지만 정렬 된 컬렉션을

2

귀하의 객체가 Comparable, 그리고 아마도 당신이 너무 equals()을 구현했지만, 오브젝트의 해시와 HashSets 계약이 없으며, 확률은 (당신이 hashCode()를 구현하지 않은 있습니다 또는 hashCode()의 구현이 (a.equals(b) == true)를 두 개체의 동일한 해시를 반환하지 않습니다.

4

HashSet에 추가되는 중복을 방지하기 위해 hashCode()equals() 방법을 사용합니다. 첫째, 당신이 원하는 객체의 해시 코드를 가져옵니다 추가 한 다음 해당하는 버킷을 찾습니다. hat 해시 코드를 만들고 해당 버킷의 각 객체를 반복하여 equals() 메소드를 사용하여 세트에 동일한 객체가 이미 있는지 확인합니다.

HashSet과 함께 사용되지 않으므로 디버거가 compareTo()에 도달하지 않습니다!

규칙은 다음과 같습니다

  1. 이 경우 객체는, 자신의 해시 코드 동일해야합니다 동일하다.

  2. 그러나 두 객체의 해시 코드 가 동일한 경우,이 이 오브젝트가 동일한 을 의미하지 않습니다! 두 개체가 같은 해시를 가질 수 있습니다. 당신이 클래스 배터리의 객체를 생성 이제까지는 JVM 새로운 공간이 필요하고 독특한 해시 코드 당신이 HashSet의에서 개체를 추가 할 때마다 반환

1

. hashCode() 메서드를 오버라이드하지 않았기 때문에 객체의 값에 의존하지 않으므로 프로그램에서 생성 된 모든 객체와 함께 고유 한 hashCode를 반환하는 객체 클래스 hashCode() 메서드를 호출합니다.

솔루션 :

재정 해시 코드()등호() 방법 및 클래스의 특성에 따라 논리를 적용합니다. 등호 및 해시 계약

http://www.ibm.com/developerworks/java/library/j-jtp05273/index.html명이 큰 실수 발생하는 무시하는 경향이

+0

제공된 링크는 매우 유용하며 나를 좋아하는 사람들에게는 매우 유용합니다. –

2

한 가지를 읽어 보시기 바랍니다. equals 메서드를 정의하는 동안 항상 매개 변수를 개체 클래스로 사용하고 개체를 원하는 클래스로 변환하십시오. 예를 들어

public bolean equals(Object aSong){ 
    if(!(aSoneg instanceof Song)){ 
     return false; 
    } 
    Song s=(Song) aSong; 
    return getTitle().equals(s.getTitle()); 
    } 

를 들어 u는 노래 aSong 대신 객체 aSong 당신의 equals 메소드를 쓰기 전달하는 경우는 호출되지 얻을 않습니다.

호프가 도움이 되었기를 바랍니다.

관련 문제