산열 집합의 HashCode & Equals

4117 단어

해시코드가 뭐예요?


  hashCode는 jdk에서 '대상의 주소' 에 따라 산출한 int 형식의 수치입니다. (Object류가 정의한hashCode 방법이라고 합니다. 이 방법의 역할은 해시 코드 값인 한 줄의 숫자가 서로 다른 대상을 대상으로 확실히 다른 정수를 되돌려주는 것입니다. 그러나 하위 클래스가 이 방법을 다시 썼다면 반드시 그렇지는 않습니다. 이 방법을 어떻게 다시 쓰는지 귀신이 알았기 때문입니다.)public int hashCode()가 객체의 해시 코드 값을 반환합니다.이 방법을 지원하는 것은 해시 테이블 (java.util.Hashtable에서 제공하는 해시 테이블) 의 성능을 향상시키기 위해서입니다.그러니까 서로 다른 대상은 귀신이 이 대상에게 무슨 짓을 했는지 알면 같은hashcode값을 생성할 수 있다.같은 대상이 생성한hashcode는 반드시 같다

hashCode의 역할, 그리고 왜 가끔씩 hashCode를 복사해야 합니까?


컨테이너 유형을 포함하는 프로그램 설계 언어는 기본적으로hashCode와 관련된다.자바에서도 마찬가지로hashCode 방법의 주요 역할은 산열 기반의 집합(무질서 집합)에 맞추기 위한 것이다. 이런 산열 집합은 Set 인터페이스,Queue 인터페이스,Map 인터페이스를 포함한다.   왜 이렇게 말할까?집합에 대상을 삽입할 때 집합에 이미 존재하는 대상이 있는지 아닌지를 어떻게 판별합니까?(주의: 산열 집합에서 중복을 허용하지 않는 원소가 존재한다) 대다수 사람들은 equals 방법을 사용해서 하나씩 비교할 생각을 하는데 이 방법은 확실히 가능하다.그러나 집합에 이미 만 개의 데이터나 더 많은 데이터가 존재한다면 equals 방법으로 하나하나 비교하면 효율은 반드시 문제가 될 것이다.이때hashCode방법의 작용은 새로운 대상을 추가할 때 이 대상의hashCode방법을 먼저 호출하여 대응하는hashcode값을 얻는다. 실제로hashMap의 구체적인 실현에서 이미 저장된 대상의hashcode값을 한table로 저장한다. 만약table에 이hashcode값이 없으면 바로 저장할 수 있고 비교를 하지 않아도 된다(이렇게 하면 그의 효율을 크게 높일 수 있다).
그러면 대상의hashcode(해시 코드 값)를 어떻게 얻는지 살펴봅시다.
String 클래스를 예로 들면 다음과 같습니다.
public int hashCode() {
        int h = hash;
        if (h == 0 && count > 0) {
            for (int i = 0; i < count; i++) {
                h = 31 * h + charAt(i);
            }
            hash = h;
        }
        return h;
    }

문자열이 다르면 그들의hashcode가 다른가?보기: (원본 공식에 따라 변환된 해시 코드 값) "Aa"= "A"* 31 + a"= 2112"BB"="B"* 31 +"B"= 2112 답안은 분명히 정해지지 않은 것이 정상이다. 이것은 String류가hashCode 방법과 equals 방법을 다시 썼기 때문이다.
요점은 순전히 개인적인 이해입니다. 부당하면 아낌없이 가르쳐 주십시오. 왜hashCode방법과 equals방법을 다시 써야 합니까?어차피 배불리 먹은 게 아니라 앞에서 말했듯이 집합에 새로운 대상을 추가할 때 이 대상의hashCode 방법을 사용해서 대응하는hashcode 값을 얻는다. 실제적으로hashMap의 구체적인 실현에서 이미 저장된 대상의hashcode 값을 하나의 테이블로 저장한다. 만약에 테이블에 이hashcode 값이 없다면 바로 저장할 수 있고 비교를 하지 않아도 된다(이렇게 하면 그 효율을 크게 높일 수 있다).다시 말해봐. 아껴서 위로 뒤집어.스트링이라는 종류를 가지고 이것은 소가 이미 우리를 위해 봉해 놓은 종류이다. 만약 당신이 성능을 추구한다면 이 종류를 참고로 설명할 수 있다. 만약에 스트링류가 이 두 가지 방법을 다시 쓰지 않았다면 어떻게 될까?물론 내가 new에 문자열을 하나 넣었는데 어떤 산열 집합에 삽입하면 문자열의 내용이 무엇이든 삽입된다. 그들이 되돌아온hashCode가 다르기 때문에 앞에서 왜 다른지 설명한다. 그러면 산열 집합의 원소의 유일성 원소의 유일성은 주로 대상의 속성 내용을 말하는 것이지 대상을 말하는 것이 아니다. 그래서 복사한hashCode는 내용에 따라 생성된 것이다. 알겠지?만약 String 클래스가hashCode 방법만 복사한다면, "aa"","aa "두 문자열은 되돌아오는hashCode는 같지만 (복사하지 않으면 달라서 꽂을 수 있습니다) 원본 코드에 삽입할 수 있기 때문입니다.
public boolean equals(Object obj) {
      return (this == obj);
  }
 false, , 

String 클래스에서는
  public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String) anObject;
            int n = count;
            if (n == anotherString.count) {
                int i = 0;
                while (n-- != 0) {
                    if (charAt(i) != anotherString.charAt(i))
                            return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }
 true !

총결산


이렇게 많이 말했는데 산열 집합의 원소 유일성을 기억하면 주로 대상의 내용을 말한다.예를 들어 String 클래스는 그 두 가지 방법을 복사해서 같은 내용의 문자열을 삽입하지 못하게 한다.만약 당신의 프로젝트 성능 요구가 극히 엄격한 지경에 이르지 않았다면, 당신이 디자인한 실체류는 이 두 가지 방법을 복사할 필요가 없지만, 복사하지 않으면 대상 속성 내용이 같아도 삽입될 것이다.만약 집합 안의 원소 내용이 다르다면, 이 두 가지 방법을 다시 써야 한다.원칙은 스트링 종류와 같다.hashCode의 일반적인 협정은 자바 응용 프로그램이 실행되는 동안 같은 대상에 대해hashCode 방법을 여러 번 호출할 때 같은 정수를 일치하게 되돌려야 한다는 것이다. 전제는 대상을 equals와 비교할 때 사용하는 정보가 수정되지 않았다는 것이다.한 응용 프로그램의 한 번 실행에서 같은 응용 프로그램의 다른 실행까지 이 정수는 일치할 필요가 없다.만약 equals (Object) 방법에 따라 두 대상이 같다면, 이 두 대상 중의 모든 대상에 대해hashCode 방법을 호출하면 같은 정수 결과를 생성해야 한다.만약에 equals(java.lang.object) 방법에 따라 두 대상이 같지 않다면 이 두 대상 중 어느 한 대상에서hashCode 방법을 호출하면 반드시 다른 정수 결과를 생성하는 것을 요구하지 않는다.그러나 프로그래머는 서로 다른 대상을 위해 서로 다른 정수를 생성하면 해시표의 성능을 향상시킬 수 있다는 것을 깨달아야 한다.실제로 Object 클래스에 의해 정의된 hashCode 메서드는 객체마다 다른 정수를 반환합니다.(이것은 일반적으로 이 대상의 내부 주소를 하나의 정수로 바꾸는 것으로 이루어지지만 자바TM 프로그래밍 언어는 이런 실현 기교가 필요하지 않다.)

좋은 웹페이지 즐겨찾기