equals와hashcode 왜 같이 써요?

6850 단어
object 대상 중의public boolean equals(Object obj)는 빈 인용 값이 아닌 x와 y에 대해 x와 y가 같은 대상을 인용할 때만 이 방법은true로 되돌아간다.주의: 이 방법이 다시 쓰일 때, 보통 hashCode 방법을 다시 써서,hashCode 방법의 일반적인 협정을 유지할 필요가 있으며, 이 협정은 같은 대상이 똑같은 해시 코드를 가지고 있어야 한다.
다음과 같습니다.
(1)obj1.equals(obj2)가true일 때obj1.hashCode() == obj2.hashCode()는 true여야 합니다.
(2)당obj1.hashCode() == obj2.hashCode()가 false인 경우 obj1.equals(obj2)는false가어야 합니다. equals를 다시 쓰지 않으면 대상의 인용이 같은 메모리 주소를 가리키는지 비교합니다. 다시 쓴 다음에 두 대상의value 값이 같은지 비교하기 위해서입니다.특히 equals를 이용하여 8대 포장 대상(예를 들어 int,float 등)과 String 클래스(이 클래스가 equals와hashcode 방법을 다시 썼기 때문에) 대상을 비교할 때 기본적으로 비교하는 것은 값이고 다른 사용자 정의 대상을 비교할 때 모두 비교하는 인용 주소hashcode는 산열 데이터의 빠른 접근에 사용된다. 예를 들어HashSet/HashMap/Hashtable 클래스를 이용하여 데이터를 저장할 때모두 저장 대상의hashcode값에 따라 동일 여부를 판단한다.이렇게 하면 만약에 우리가 한 대상에 대해 euqals를 다시 썼다면 대상의 구성원 변수 값이 모두 같다면 euqals는true와같지만hashcode를 다시 쓰지 않는다면 우리는 새로운 대상을 다시 new로 하고 원래의 대상으로 삼는다.equals(새 대상)가true와 같을 때 양자의hashcode는 다르기 때문에 이해의 불일치가 발생할 수 있다. 예를 들어 산열 집합을 저장할 때(Set류) 두 개의 값이 같은 대상을 저장하여 혼동을 초래할 수 있기 때문에hashcode()의 예를 들어 설명을 다시 써야 한다.
import java.util.HashSet;
import java.util.Set;

/**
 * @author: xbq
 * @date: 2019/2/13 16:47
 * @description:
 */
public class XbqTest {
    public static void main(String[] args) {
        Name n1 = new Name("01");
        Name n2 = new Name("01");

        Set c = new HashSet();
        c.add(n1);
        System.out.println("------1------");
        c.add(n2);
        System.out.println("------2------");
        System.out.println(n1.equals(n2));
        System.out.println("------3------");
        System.out.println(n1.hashCode());
        System.out.println(n2.hashCode());
        System.out.println(c);
    }
}

class Name {
    private String id;

    public Name(String id) {
        this.id = id;
    }

    public String toString(){
        return this.id;
    }

    /**
     *   equals  
     * @param obj
     * @return
     */
    public boolean equals(Object obj) {
        if (obj instanceof Name) {
            Name name = (Name) obj;
            System.out.println("equal"+ name.id);
            return (id.equals(name.id));
        }
        return super.equals(obj);
    }

    /**
     *   hashCode  
     * @return
     */
    public int hashCode() {
        Name name = (Name) this;
        System.out.println("Hash" + name.id);
        return id.hashCode();
    }
}

실행 결과:
Hash01
------1------
Hash01
equal01
------2------
equal01
true
------3------
Hash01
1537
Hash01
1537
[01]

Name 클래스에서 equals 메서드를 설명하지 않으면 다음과 같은 결과가 실행됩니다.
Hash01
------1------
Hash01
------2------
false
------3------
Hash01
1537
Hash01
1537
[01, 01]

Name 클래스에서 hashCode 메서드를 설명하면 다음과 같은 결과가 실행됩니다.
------1------
------2------
equal01
true
------3------
942731712
971848845
[01, 01]

이 프로그램을 분석한 결과 처음 추가할 때hashcode() 방법을 호출하여hashcode를 대상에 저장하고 두 번째도 마찬가지로hashcode를 비교했다.hashcode도HashSet/HashMap/Hashtable 클래스에만 데이터를 저장하기 때문에 비교에 사용되며 다시 써야 합니다
총괄적으로 말하면 사용자 정의 클래스는 equals 방법을 다시 써서 등치 비교를 하고 사용자 정의 클래스는compareTo 방법을 다시 써서 서로 다른 대상의 크기를 비교한다.hashcode 방법을 다시 써서HashSet/HashMap/Hashtable 클래스에 데이터를 저장할 때 비교한다

좋은 웹페이지 즐겨찾기