Java에서 객체 해시 코드 값을 찾는 데 사용되는 hashCode () 함수 이해

4691 단어 JavahashCode
이해
hashCode()의 역할은 해시 코드를 얻는 것이고 해시 코드라고도 부른다.이것은 실제로 int 정수를 되돌려줍니다.이 해시 코드의 역할은 이 대상이 해시 테이블에 있는 색인 위치를 확인하는 것이다.
hashCode()는 JDK의 Object에 정의됩니다.자바에서 이것은 자바의 모든 종류에hashCode () 함수가 포함되어 있음을 의미합니다.
각 Java 클래스에는 hashCode() 함수가 포함되어 있지만단, "클래스의 산목록"을 만들고 (아래 설명 참조) 이 클래스의hashCode () 만 유용합니다. (역할은 클래스의 모든 대상이 산목록에 있는 위치를 확인하는 것입니다. 다른 경우 (예를 들어 클래스의 단일 이미지를 만들거나 클래스의 대상 그룹을 만드는 등) 클래스의hashCode () 는 작동하지 않습니다.
위의 산목록은 자바 집합에서 본질은 산목록의 종류를 가리킨다. 예를 들어HashMap,Hashtable,HashSet이다.
즉, 해시코드 () 는 흩어진 목록에 있어야 쓸모가 있고, 다른 상황에서는 쓸모가 없다.산열 목록에서hashCode()의 역할은 대상의 산열 코드를 가져와 이 대상이 산열 목록에 있는 위치를 확인하는 것이다.
우리는 모두 알고 있다. 산열표는 키 값 쌍(key-value)을 저장하는데, 그 특징은 키에 따라 대응하는 값을 신속하게 검색할 수 있다는 것이다.그중에 산열 코드를 이용했어요!
산목록의 본질은 수조를 통해 이루어진다.우리가 산 목록의 어떤'값'을 얻으려고 할 때, 실제로는 그룹의 어떤 위치의 요소를 얻으려고 한다.수조의 위치는 바로 "키"를 통해 얻는 것이다.더 나아가 수조의 위치는'키'에 대응하는 산열 코드를 통해 계산된 것이다.
다음은 HashSet을 예로 들어hashCode()의 작용을 깊이 있게 설명합니다.
HashSet에 이미 1000개의 요소가 있다고 가정합니다.100번째 요소를 삽입할 때 어떻게 처리해야 합니까?HashSet은 Set 컬렉션이므로 반복 요소가 허용됩니다.
"1001번째 요소를 앞의 1000개 요소와 하나씩 비교"?분명히 이 효율은 상등저하다.산열 목록은 이 문제를 잘 해결했다. 원소의 산열 코드에 따라 원소가 산열 목록에 있는 위치를 계산한 다음에 원소를 이 위치에 삽입하면 된다.같은 원소에 대해서는 자연히 하나만 보존되었다.
이로부터 알 수 있듯이 만약 두 원소가 같다면 그들의 산열 코드는 반드시 같다.하지만 반대로 꼭 그렇지는 않다.흩어진 목록에서
1. 만약 두 대상이 같다면 그것들의hashCode() 값은 반드시 같아야 한다.
2. 두 객체가 hashCode()와 같으면 반드시 같지는 않습니다.
주의: 이것은 흩어진 목록에 있는 상황입니다.비산 목록에서 반드시 이렇다!
예제
구체적인 예시를 살펴보자.

public class HashTest { 
  private int i; 
 
  public int getI() { 
    return i; 
  } 
 
  public void setI(int i) { 
    this.i = i; 
  } 
 
  public int hashCode() { 
    return i % 10; 
  } 
 
  public final static void main(String[] args) { 
    HashTest a = new HashTest(); 
    HashTest b = new HashTest(); 
    a.setI(1); 
    b.setI(1); 
    Set<HashTest> set = new HashSet<HashTest>(); 
    set.add(a); 
    set.add(b); 
    System.out.println(a.hashCode() == b.hashCode()); 
    System.out.println(a.equals(b)); 
    System.out.println(set); 
  } 
} 

이 출력의 결과:

true 
false 
[com.ubs.sae.test.HashTest@1, com.ubs.sae.test.HashTest@1] 

상기 예시에서 우리는hashCode 방법을 다시 썼을 뿐이다. 위의 결과를 통해 알 수 있듯이 두 대상의hashCode는 같지만 실제로 두 대상은 같지 않다.우리는 equals 방법을 다시 쓰지 않았습니다. 그러면 Object의 기본 equals 방법을 사용합니다. 두 대상의 인용이 같은지 아닌지를 비교합니다. 이것은 두 개의 다른 대상입니다. 두 대상의 인용은 틀림없이 정해지지 않은 것입니다.여기서 우리는 생성된 대상을 HashSet에 넣었고 HashSet에는 유일한 대상, 즉 같은 (equals 방법에 적용) 대상만 저장할 수 있었다. 그러나 여기는 사실상 두 대상인 a, b가 모두 HashSet에 저장되었다. 그러면 HashSet은 그 자체의 의미를 잃었다.
이때 우리는 equals 방법을 덧붙인다.

public class HashTest { 
  private int i; 
 
  public int getI() { 
    return i; 
  } 
 
  public void setI(int i) { 
    this.i = i; 
  } 
 
  <span style="color:#3366FF;"><strong>public boolean equals(Object object) { 
    if (object == null) { 
      return false; 
    } 
    if (object == this) { 
      return true; 
    } 
    if (!(object instanceof HashTest)) { 
      return false; 
    } 
    HashTest other = (HashTest) object; 
    if (other.getI() == this.getI()) { 
      return true; 
    } 
    return false; 
  }</strong></span> 
 
  public int hashCode() { 
    return i % 10; 
  } 
 
  public final static void main(String[] args) { 
    HashTest a = new HashTest(); 
    HashTest b = new HashTest(); 
    a.setI(1); 
    b.setI(1); 
    Set<HashTest> set = new HashSet<HashTest>(); 
    set.add(a); 
    set.add(b); 
    System.out.println(a.hashCode() == b.hashCode()); 
    System.out.println(a.equals(b)); 
    System.out.println(set); 
  } 
} 
결과는 다음과 같습니다.

true 
true 
[com.ubs.sae.test.HashTest@1] 

결과에서 알 수 있듯이 현재 두 대상은 완전히 같다. HashSet에도 한 개의 대상만 저장되어 있다.
총결산
1. 해시코드의 존재는 주로 검색의 신속성에 사용된다. 예를 들어 해시테이블, 해시맵 등이다. 해시코드는 산열 저장 구조에서 대상의 저장 주소를 확정하는 데 사용된다.
2. 만약에 두 대상이 같다면 equals(java.lang.Object) 방법에 적용된다면 이 두 대상의hashCode는 반드시 같아야 한다.
3. 만약에 대상의 equals 방법이 다시 쓰인다면 대상의 hashCode도 가능한 한 다시 쓰고hashCode가 사용하는 대상을 생성하려면 반드시 equals 방법에서 사용하는 것과 일치해야 한다. 그렇지 않으면 위에서 언급한 두 번째 점을 위반할 수 있다.
4. 두 대상의hashCode는 같다. 반드시 두 대상이 같다는 것은 아니다. 즉, equals(java.lang.Object) 방법에 적용되지 않고 이 두 대상이 산열 저장 구조에 있다는 것만 설명할 수 있다. 예를 들어hashtable는 그들이'같은 바구니에 저장한다'는 것이다.

좋은 웹페이지 즐겨찾기