2014-09-19 10 views
1

고유 ID로 final String 클래스가 있습니다. 물론 equals를 재정의하려고하므로 비교는 ID에만 기반합니다. 아래와 같이 ID의 해시 코드를 반환하는 것이 올바른 방법입니까?클래스에 대한 클래스 멤버의 해시 코드를 사용할 수 있습니까?

class ItemSpec{ 
    final String name; 

    ... 

    @Override 
    public boolean equals(Object o){ 
     if(o != null && o instanceof ItemSpec){ 
      return name.equalsIgnoreCase(((ItemSpec)o).name); 
     } else{ 
      return false; 
     } 
    } 

    @Override 
    public int hashCode(){ 
     if(name == null){ 
      return 0; 
     } else{ 
      return name.hashCode(); 
     } 
    } 
} 
+4

예, 그것은 괜찮습니다 .. –

+7

주 당신의 'equals' 메쏘드는'name'이 널이 아니라고 가정합니다. 그러나'hashCode' 메쏘드는 그것을 가정합니다. 무엇 이니? –

+0

@JonSkeet 죄송합니다. 추가 한 후에 나타났습니다. 편집 됨. – NoMercyIncluded

답변

12

동등한 문자는 대소 문자를 구분하지 않습니다. ItemSpec이 같지만 다른 해시 코드로 나오게 할 수 있습니다. 이는 해시 코드의 가장 중요한 요구 사항을 해칩니다.

equalshashCode에 동의해야합니다. 그러므로 대소 문자를 구분하지 않으면 대소 문자를 구분하지 않아야합니다.

@Override 
public int hashCode(){ 
    if (name == null){ 
     return 0; 
    } else{ 
     return name.toLowerCase().hashCode(); 
    } 
} 

또한 hashCode 방법은 name가 null이 될 수 있음을 의미한다. 그렇다면 equals 메소드에서도 null을 확인해야합니다.

+2

'a.equalsIgnoreCase (b)'가 아니라 a.toLowerCase(). equals (b.toLowerCase())가 false 인 경우는 없습니까? – assylias

+1

좋은 캐치지만 assylias와 동일하게 지적하고 싶었습니다. 전환으로 로캘 별 및 유니 코드 관련 번거 로움이 생길 수 있습니다. – Marco13

+0

글쎄, 내가 직접 깨닫고 편집했지만, 선생님은 너무 빠릅니다. 나); – NoMercyIncluded

-1

나는 당신의 접근 방식에 어떤 문제도 보지 못했다.

그러나, 나는 종종 다음과 같은 구현을 본 적이 :

public int hashCode() { 
    final int prime = 31; 
    int result = super.hashCode(); 
    result = prime * result + ((name == null) ? 0 : name.hashCode()); 
    return result; 
} 

업데이트 : 여기 이 더 나은 설명과 함께 링크입니다 : Best implementation for hashCode method

+0

자동 생성 된 코드처럼 보이고 연산 시간을 늘리는 것과 별개로 ... – assylias

+5

equals에서'super.equals'를 요구하지 않으면'super.hashCode'를 해시 코드에 포함시킬 수 없습니다 방법. 그렇지 않은 경우 두 개의 동일한 객체가 서로 다른 해시 코드를 가질 수 있습니다. – khelwood

+0

나는이 코드를 내 프로젝트에서 가져 갔다. 내가 수동으로 해본다면 100 % 확신 할 수 없다. 또는 이클립스가 생성되었다. 하지만 hashCode를 구현하는 가장 일반적인 방법을 살펴 보았습니다.이 방법이 가장 일반적인 방법이었습니다. –