5

이 질문에는 이미 답변이 있습니다.

나는 물어 보았다비슷한 질문string.GetHashCode().NET의 메소드. 그때부터, 우리는 다른 머신에서 사용하기 위해 buit-in 타입에 대한 해시 코드의 암시 적 구현에 의존 할 수 없다는 것을 배웠습니다. 따라서, 나는 자바 구현을 가정하고있다.String.hashCode()다른 하드웨어 구성에서 불안정하며 VM간에 다르게 작동 할 수 있습니다 (다른 VM 구현을 잊지 마십시오)

현재 해시 알고리즘을 사용하여 문자열을 자바로 숫자로 안전하게 변환하는 방법에 대해 논의하고 있지만 해시 알고리즘은 클러스터의 여러 노드에서 안정적이어야하며 사용 빈도가 높기 때문에 평가가 빠르다. 우리 팀 동료들은 네이티브hashCode방법이 필요하며, 다른 접근 방식을 재고하기 위해 합리적인 논의가 필요할 것입니다. 현재, 머신 구성 (x86과 x64)의 차이점, 알고리즘이있는 머신에 따라 일부 머신 (우리의 경우에는 거의 적용 할 수 없음) 및 바이트 순서 차이에 따라 JVM의 다른 벤더 만 생각할 수 있습니다 운영. 물론 문자 인코딩도 고려해야 할 것입니다.

이 모든 것들이 내 마음 속으로 들어오지 만, 나는 그들 중 어느 누구도 강한 이유가 될 것이라고 100 % 확신하지 못하고,이 분야에서 당신의 전문화와 경험에 감사드립니다. 이렇게하면 맞춤 해싱 알고리즘을 작성하는 데 도움이되는 강력한 주장을 세우는 데 도움이됩니다. 또한, 무엇에 대한 조언을 주시면 감사하겠습니다.하지 않기그것을 구현할 때.


  • String 해시 코드는 모든 Java 플랫폼에서 잘 정의되고 동일합니다. - ZhongYu
  • stackoverflow.com/questions/785091/… - zch
  • @ zhong.j.yu 귀하가 가정합니다.JRockitIBM JVM~에 대한 동일한 구현을 가짐String#hashCode. - Luiggi Mendoza
  • @ zhong.j.yu, 소스 코드에 따르면String클래스, 그것은 충분히 안정 보인다. 그러나 .NET에서 발생하는 것처럼 여기에 의존하지 않는 이유가 있습니다. 가상 머신, 하드웨어 차이 및 바이트 순서 또는 인코딩 종류를 염두에두면 자바 사례는 저와 매우 비슷합니다. - Ivaylo Slavov
  • @ zhong.j.yu해야하지만, 규칙을 전혀 따르지 않는 업체도 있습니다. - Luiggi Mendoza

2 답변


11

구현String.hashCode()~이다.지정된문서에서 일관성이 보장됩니다.

String 객체의 해시 코드는 다음과 같이 계산됩니다.

  s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

int 산술을 사용합니다. 여기서 s [i]는 문자열의 i 번째 문자이고, n은 문자열의 길이이고 ^는 지수입니다. 빈 문자열의 해시 값은 0입니다.

이러한 모든 작업은 Java 용 플랫폼 독립적으로 구현됩니다. 예를 들어 플랫폼 바이트 순서는 무의미합니다.

즉,점점에이String파일이나 다른 바이트 소스에서 가져 오는 경우 까다로울 수 있습니다. 이 경우 명시 적으로Charset. (기억Strings은 다른 인코딩 자체가 없습니다. 인코딩은전환~ 사이byte[]String.)


  • 모든 사양 (및 내가 알고있는 핵심 자바 구성 요소)에 관한 한, 실제로 충분히 안전 해 보인다. 감사 - Ivaylo Slavov

3

당신은소스 코드. 내가 볼 수있는 것부터 (10 초의 분석이 끝나면) 이것은 기계와 아키텍처간에 안정적이어야합니다. 루이는 사양을 인용하여이를 확인합니다. 스펙을 믿는다면 더 좋습니다. :-)

그러나 다른 JRE가 다르게 구현하고 스펙을 위반하는 경우에는 다를 수 있습니다.

public int hashCode() {
    int h = hash;
    if (h == 0) {
        int off = offset;
        char val[] = value;
        int len = count;

        for (int i = 0; i < len; i++) {
            h = 31*h + val[off++];
        }

        hash = h;
    }

    return h;
}


  • 답변 주셔서 감사합니다. 나는 소스 코드를 직접 보았고 문제가 될만한 것을 찾지 못했다. 그래도 무언가 잘못 될 수있는 유일한 곳이 아니라고합니다. 바라건대, 같은 클러스터에있는 다른 JVM (다른 벤더)은 우리에게 적합하지 않을 것이다. - Ivaylo Slavov
  • 나는 만약 벤더가 스펙을 깨면 당신은 많은 Strings를 실행하고 공식적인 결과와 비교할 수 있다고 생각합니다. 일부를 실행해야합니다.사람. 자바의 초창기에는 hashCode 메소드가 처음 16 자 (32 자 일 수도 있음) 만 고려했습니다. 비슷한 일을함으로써 벤더 마크를 얻으려는 벤더를 볼 수있었습니다. - user949300
  • 좋은 조언, 그것을 공유해 주셔서 감사합니다. 언젠가는 그 지식이 꽤 유용 할지라도, 우리는 Oracle의 JVM을 고수 할 것입니다. 그것에 대한 생각을 가지고, 그러한 "성능 이득" 바람직하지 않고 예측할 수없는 많은 행동을 요할 수도 있습니다. 거기에있는 JVM 공급 업체가 해당 카테고리에 속할 수 있는지 궁금합니다. - Ivaylo Slavov

연결된 질문


관련된 질문

최근 질문