문제

Java에는 서브 클래스가 있습니다 Vertex Java3d 클래스의 Point3f. 지금 Point3f 계산합니다 equals() 좌표의 값을 기반으로하지만 Vertex 클래스 나는 더 엄격 해지고 싶습니다 : 두 개의 정점은 동일한 대상 인 경우에만 동일합니다. 여태까지는 그런대로 잘됐다:

class Vertex extends Point3f {

    // ...

    public boolean equals(Object other) {
        return this == other;
    }
}

나는 이것이 계약을 위반한다는 것을 알고 있습니다 equals(), 그러나 나는 정점을 다른 정점과 만 비교할 것이기 때문에 이것은 문제가되지 않습니다.

이제 정점을 HashMap,, hashCode() 방법은 일치하는 결과를 반환해야합니다 equals(). 그것은 현재 그렇게하지만 아마도 그 반환 가치는 Point3f, 따라서 해시 충돌이 다르게 해줄 것입니다 Vertex 동일한 좌표를 가진 객체.

그러므로 나는 기반을 원합니다 hashCode() 객체의 주소에서 Vertex필드. 나는 그것을 알고있다 Object 클래스는 이것을하지만, 나는 그것을 부를 수 없습니다 hashCode() 방법 때문에 Point3f 그것을 무시합니다.

따라서 실제로 내 질문은 두 가지입니다.

  • 그런 얕은 것을 원해야합니다 equals()?
  • 그렇다면 해시 코드를 계산하기 위해 객체의 주소를 어떻게 얻습니까?

편집 : 난 그냥 뭔가를 생각 했어 ... 나는 무작위를 생성 할 수있다 int 객체 생성에 가치가 있고 해시 코드에 사용하십시오. 좋은 생각인가요? 왜 안 돼)?

도움이 되었습니까?

해결책

system.identityHashCode ()를 사용하거나 IdentityHashMap을 사용하십시오.

다른 팁

System.identityHashCode() 기본 메소드에서 반환 할 수있는 주어진 개체에 대해 동일한 해시 코드를 반환합니다. hashCode(), 주어진 객체의 클래스가 재정의 여부 hashCode().

이도 대의원을 사용합니다 대답 아마 더 낫다.


class Vertex extends Point3f{
   private final Object equalsDelegate = new Object();
   public boolean equals(Object vertex){
      if(vertex instanceof Vertex){
         return this.equalsDelegate.equals(((Vertex)vertex).equalsDelegate);
      }
      else{
         return super.equals(vertex);
      }
   }
   public int hashCode(){
      return this.equalsDelegate.hashCode();
   }
}

FYI, 귀하의 평등 방법은 평등 계약을 위반하지 않습니다 (기본 객체의 계약의 경우)은 기본적으로 기본 객체 메소드의 평등 방법입니다. 좋아.

해시 코드의 경우, 허용 된 답변은 좋은 옵션이며 해시 테이블에 동일한 값을 가진 정점 키가 많이 포함되어 있으면 훨씬 더 효율적입니다.

변경할 필요가없는 이유는 해시 코드가 False를 반환하는 객체에 대해 동일한 값을 반환하는 것이 완전히 정상이기 때문입니다. 사례. 해시 테이블에 효율적인지 여부는 완전히 다른 문제입니다 ... 많은 객체에 동일한 해시 코드가 있으면 더 많은 충돌이 발생할 수 있습니다 (해시 코드를 단독으로 남겨두고 정점이 많은 경우에 해당 될 수 있습니다. 같은 값으로).

물론 대답으로 받아들이지 마십시오 (물론 선택한 것은 훨씬 더 실용적입니다), 나는 당신에게 해시 코드와 동등한에 대한 배경 정보를 조금 더주고 싶었습니다 ;-).

처음에 hashcode ()를 무시하려는 이유는 무엇입니까? 다른 평등의 정의로 작업하고 싶다면 그렇게하고 싶을 것입니다. 예를 들어

공개 클래스 A {int id;

public boolean equals (a other) {return other.id == id} public int hashcode () {return id;}

} id가 동일하다면 객체가 동일하고 해시 코드를 무시하여 이것을 할 수 없다는 것을 명확히하고 싶은 곳.

Hashset Hash = New Hashset (); hash.add (new a (1)); hash.add (new a (1)); 그리고 평등의 정의의 관점에서 2 개의 동일한 2를 얻으십시오. 그러면 올바른 동작은 해시에 1 개의 객체 만 있으면 두 번째 쓰기가 덮어 쓰는 것입니다.

당신은 평등을 논리적 비교로 사용하지 않고 물리적 인 것 (즉, 동일한 개체)를 사용하기 때문에 해시 코드가 고유 한 값을 반환 할 것을 보장하는 유일한 방법은 자신의 제안의 변형을 구현하는 것입니다. 임의의 숫자를 생성하는 대신 UUID를 사용하여 각 객체에 대한 실제 고유 값을 생성하십시오.

system.identityHashCode ()가 작동하고 대부분 당시의 경우 객체로 보장되지 않습니다. hashcode () 메소드는 ~ 아니다 모든 객체에 대해 고유 한 값을 반환하도록 보장합니다. 한계 사례가 발생하는 것을 보았고 아마도 VM 구현에 의존 할 것입니다. 이는 코드에 의존하는 것이 아닙니다.

Object.hashCode ()에 대한 Javadocs에서 발췌 : 합리적으로 실용적으로 클래스 객체로 정의 된 해시 코드 메소드는 별개의 객체에 대해 별개의 정수를 반환합니다. (이것은 일반적으로 객체의 내부 주소를 정수로 변환하여 구현되지만 Javatm 프로그래밍 언어는이 구현 기술이 필요하지 않습니다.)

이 문제는 해시 맵에 삽입 될 때 서로 삽입 될 때 서로를 덮어 쓰는 것이 두 개의 별도 포인트 객체가있는 경우입니다. 둘 다 동일한 해시가 있기 때문입니다. 논리적 평등이 없으므로 hashcode ()의 재정의와 함께, IdentityHashCode 메소드는 실제로이 시나리오가 발생할 수 있습니다. 논리적 인 경우가 동일한 논리적 지점에 대한 해시 항목 만 교체하는 경우, 시스템 기반 해시를 사용하면 두 객체와 함께 발생할 수 있습니다. 평등 (및 클래스조차도)은 더 이상 요인이 아닙니다.

함수 hashcode ()는 객체에서 상속되며 의도 한대로 (좌표 수준이 아닌 객체 레벨에서) 정확하게 작동합니다. 변경할 필요가 없어야합니다.

평등 한 방법에 관해서는, 코드를 사용하는 대신 코드에서 OBJ1 == OBJ2를 수행 할 수 있기 때문에 사용해야 할 이유가 없습니다. 정렬을위한 것이기 때문에 코드를 비교하고 비교하는 것이 훨씬 더 의미가 있습니다.

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