문제

재정의하는 경우 equals()함수는 java.랭.개체 javadocs 것이 좋습니다,

그것은 일반적으로 필요한 재정의하는 방법의 차이는 때마다 이 방법은 무시하므로 유지하는 일반적인 계약에 대한 방법의 차이,어느 국가 동등한 객체가 있어야 합 같은 해시 코드입니다.

의 차이()메소드를 반환해야만 합니다 정수한 각 개체에 대한(이 일을 쉽게 비교할 때는 객체를 기반으로 메모리에 위치,단순히 반환 정수한 주의 객체)

어떻게 차()메소드를 무시될도록 반환합니다 정수한 각 개체에 대한 기반에 있는 객체의 속성?


public class People{
   public String name;
   public int age;

   public int hashCode(){
      // How to get a unique integer based on name and age?
   }
}
/*******************************/
public class App{
   public static void main( String args[] ){
       People mike = new People();
       People melissa = new People();
       mike.name = "mike";
       mike.age = 23;
       melissa.name = "melissa";
       melissa.age = 24;
       System.out.println( mike.hasCode() );  // output?
       System.out.println( melissa.hashCode(); // output?
   }
}
도움이 되었습니까?

해결책

객체에 대한 해시 코드가 완전히 고유해야한다고 말하는 것은 아니며, 두 개의 동일한 객체에 대한 해시 코드가 동일한 해시 코드를 반환한다고 만 말합니다. 동일한 해시 코드를 반환하지 않는 두 개의 비등 한 객체를 갖는 것은 전적으로 합법적입니다. 그러나 고유 한 A 해시 코드 분포가 일련의 객체를 초과할수록 해시 맵 및 해시 코드를 사용하는 기타 작업에서 더 나은 성능을 얻을 수 있습니다.

Intellij Idea와 같은 IDE에는 Equals 및 Hashcode에 대한 내장 생성기가 있으며, 일반적으로 대부분의 객체에 대한 "충분한"코드를 제시하는 데 꽤 잘 작동합니다 (아마도 손으로 만들어진 지나치게 고갈 된 해시 함수보다 낫습니다).

예를 들어, 여기에는 아이디어가 사람들의 클래스를 위해 생성되는 해시 코드 기능이 있습니다.

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

다른 팁

Marc가 이미 다루었으므로 해시 코드 고유성의 세부 사항에 대해서는 가지 않을 것입니다. 당신을 위해 People 수업, 먼저 사람의 평등이 무엇을 의미하는지 결정해야합니다. 어쩌면 평등은 그들의 이름에만 기반을두고있을 것입니다. 아마도 이름과 나이를 기반으로 할 수도 있습니다. 도메인 특이적일 것입니다. 평등이 이름과 나이에 근거한다고 가정 해 봅시다. 당신의 우선 equals 모양이 될 것입니다

public boolean equals(Object obj) {
    if (this==obj) return true;
    if (obj==null) return false;
    if (!(getClass().equals(obj.getClass())) return false;
    Person other = (Person)obj;
    return (name==null ? other.name==null : name.equals(other.name)) &&
        age==other.age;
}

당신이 무시할 때마다 equals 당신은 무시해야합니다 hashCode. 뿐만 아니라, hashCode 계산에 더 이상 필드를 사용할 수 없습니다 equals 했다. 대부분의 경우 다양한 필드의 해시 코드를 추가하거나 독점적으로 추가해야합니다 (해시 코드는 빠르게 계산해야합니다). 그래서 유효합니다 hashCode 메소드는 다음과 같습니다.

public int hashCode() {
    return (name==null ? 17 : name.hashCode()) ^ age;
}

다음은 다음과 같습니다 유효하지 그것이 필드를 사용하기 때문에 equals (높이). 이 경우 두 개의 "동일"객체는 다른 해시 코드를 가질 수 있습니다.

public int hashCode() {
    return (name==null ? 17 : name.hashCode()) ^ age ^ height;
}

또한, 두 개의 비평가 객체가 동일한 해시 코드를 갖는 데 완벽하게 유효합니다.

public int hashCode() {    
    return age;    
}

이 경우 Jane 30 세는 Bob Age 30과 같지 않지만 해시 코드는 모두 30입니다. 유효하지만 해시 기반 컬렉션의 성능에 바람직하지 않습니다.

다른 질문이 있을 경우 몇 가지 기본적인 낮은 수준의 모든 것을 알아야 프로그래머,그리고 나는 생각 hash 조회가 그 중 하나입니다.그래서 여기에 간다.

해시 테이블(참고로 나는 사용하지 않는 실제 classname)은 기본적으로 배열의 링크 목록입니다.뭔가를 찾을 표에서,당신은 먼저 계산하는 차의 무언가는,다음 모 그것의 크기에 의해 테이블.이는 인덱스 배열로,당신은 연결 리스트에서는 인덱스입니다.당신이 통과한 다음의 목록을 찾을 때까지 귀하의 개체입니다.

이 배열 검색 O(1),연결 목록을 탐색 O(n),당신은 해시를 만드는 함수로 임의의 메일로,그래서 가능한 객체가 해시된 다른 목록입니다.모든 객체를 반환할 수 있는 값으로 0 을 차이,그리고 해시 테이블은 여전히 작동하지만 그것은 본질적으로 긴 연결 목록에서 요 0 의 배열입니다.

당신은 또한 일반적으로 배열이 큰 것으로는 기회를 증가는 개체의 목록에서의 길이 1.Java HashMap,예를 들어,증가 배열의 크기 때의 항목 수도>75%의 배열의 크기.있는 단점이 여기:할 수 있는 거대한 배열과 매우 몇 가지 항목 및 폐 메모리거나 더 작은 배열에서 각 요소에 배열과 목록>1 항과 시간을 낭비를 통과.완벽한 해시 배정하는 각 개체 고유한 위치에 배열에 낭비 없이 공간입니다.

용어"시는 것은"진짜기,그리고 일부 경우에 당신을 만들 수 있습 해쉬 기능을 제공하는 고유한 숫자가 각 개체입니다.이것은 단지 가능한 알고 있는 경우 설정의 가능한 모든 값입니다.일반적인 경우에,당신은 당신을 달성할 수 없고,있을 것입니다 일부는 값을 반환한 차이.이것은 간단한 수학:이 있는 경우 문자열에는 4 개 이상의 바이트의 길을 만들 수 없습니다 독특한 4 바이트의 차이.

하나의 재미있는 재미있는 이야기:해시 배열은 일반적으로 크기에 따라 숫자를 제공하기 위해,최고의 기회를 위한 무작위 배정할 때 모드에 관계없이 결과는 어떻게 임의의 hashcodes 니다.

편집에 기반한 의견:

1)연결 목록하지 않는 유일한 방법을 나타내는 개체는 같은 차지하는 방법을 사용하는 JDK1.5HashMap.비록 적은 메모리보다 효율적으로 간단한 배열을,그것은 틀림없이 만들이 덜 변동될 때 들추어내기 때문에(항목을 해제 하나의 버킷과 다시 연결하는 또 다른).

2)JDK1.4,HashMap 클래스는 배열을 사용하여 크기의 전원으로의 2;그 이전에 그것을 사용 2^N+1 로 나는 믿고 prime N <=32.이것은 속도가 아 배열 색인 per se,그러나지 않도록 배열 색인 것으로 계산한 비트와 아닌 사단에 의해 언급했듯이 닐 커피.개인적으로,나는 질문으로 이것을 조기 최적화,그러나 주어진 목록의 저자에 HashMap,나는 가정은 일부 실제 혜택이다.

일반적으로 해시 코드는 가능한 해시 코드 (정수)보다 더 많은 값이 있기 때문에 고유 할 수 없습니다. 좋은 해시 코드는 정수에 값을 잘 배포합니다. 나쁜 사람은 항상 같은 값을 줄 수 있고 여전히 논리적으로 정확할 수 있습니다.

동일한 값은 해시 테이블이 올바르게 작동하려면 동일한 해시 값을 가져야합니다. 그렇지 않으면 해시 테이블에 키를 추가 한 다음 다른 해시 코드로 동일한 값을 통해 찾아 보지 않으려고 노력할 수 있습니다. 또는 다른 해시 코드로 동일한 값을 넣고 해시 테이블의 다른 위치에 두 개의 동일한 값을 가질 수 있습니다.

실제로 당신은 일반적으로 hashcode ()와 equals () 메소드 모두에서 고려할 필드의 서브 세트를 선택합니다.

나는 당신이 그것을 오해했다고 생각합니다. 해시 코드는 각 객체마다 고유 할 필요는 없습니다 (결국 해시 코드). 분명히 모든 객체와 동일하기를 원하지는 않습니다. 그러나 당신은 그것이 동일 한 모든 객체와 동일해야합니다. 그렇지 않으면 표준 컬렉션과 같은 것들이 작동하지 않을 것입니다 (예 : 해시 세트에서 무언가를 찾아 볼 수는 없지만 찾지 못할 것입니다).

간단한 속성의 경우 일부 IDE에는 해시 코드 기능 빌더가 있습니다.

IDE를 사용하지 않으면 Apahce Commons 및 Class HashcodeBuilder 사용을 고려하십시오.

해시 코드에 대한 유일한 계약 의무는 일관된. 해시 코드 값을 생성하는 데 사용 된 필드는 동일하거나 동일한 방법에 사용 된 필드의 서브 세트 여야합니다. 즉, 효율적이지는 않지만 모든 값에 대해 0을 반환하는 것이 유효하다는 것을 의미합니다.

해시 코드가 단위 테스트를 통해 일관된 지 확인할 수 있습니다. 나는 추상적 인 수업을 썼다 평등 테스트 케이스, 소수의 해시 코드 점검을 수행합니다. 하나는 단순히 테스트 사례를 확장하고 2 ~ 3 개의 공장 방법을 구현해야합니다. 해시 코드가 효율적이면 테스트는 매우 조잡한 테스트 작업을 수행합니다.

이것이 해시 코드 방법에 대한 문서가 알려주는 것입니다.

@ javadoc

Java 응용 프로그램을 실행하는 동안 동일한 객체에서 두 번 이상 호출 될 때마다 해시 코드 메소드는 객체의 평등 비교에 사용 된 정보가 수정되지 않은 경우 동일한 정수를 지속적으로 반환해야합니다. 이 정수는 응용 프로그램의 하나의 실행에서 동일한 응용 프로그램의 다른 실행에 대한 일관성을 유지할 필요가 없습니다.

비즈니스 키라는 개념이있어 동일한 유형의 별도 인스턴스의 고유성을 결정합니다. 대상 도메인 (예 : 차량)에서 별도의 엔티티를 모델링하는 각 특정 유형 (클래스)에는 하나 이상의 클래스 필드로 표시되는 비즈니스 키가 있어야합니다. Methods Equals () 및 HasCode ()는 비즈니스 키를 구성하는 필드를 사용하여 구현해야합니다. 이것은 두 방법이 서로 일치하도록합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top