Jackson (버전 2.1.x)에 의존하는 Java로 작성된 JSON 스키마 구현이 있습니다. 정확성을 이유로 Jackson에게 부동 소수점 숫자에 BigDecimal
을 사용하라고 지시합니다."정규화"BigDecimal의 해시 코드 : howto?
JSON 스키마의 필요성에 대한 특별한 요구가 있습니다. JSON 값의 동일성은 숫자 값에 대해 수학적 값의 동일성으로 정의됩니다.
{ "enum": [ 1, 1.0 ] }
그러나 JsonNodes 1
및 1.0
에 대한 동일하지 : 예를 들어,이 법적 스키마 (AN enum
의 값은 고유해야합니다) 아니다, 이후 체크 이런 종류의 필요합니다. 따라서 Guava의 Equivalence 구현을 코딩하고 적절한 경우 Set<Equivalence.Wrapper<JsonNode>>
을 사용합니다. 그리고이 구현은 숫자 노드뿐 아니라 모든 유형의 노드에서 작동해야합니다.
그리고이 구현의 가장 어려운 부분은 숫자 노드 doHash()
것으로 판명는 :/나는 그들이 정수 또는 부동 소수점 숫자인지, 해당 수학적 값에 대해 동일한 해시 코드를 해야합니다.
@Override
protected int doHash(final JsonNode t)
{
/*
* If this is a numeric node, we want a unique hashcode for all possible
* number nodes.
*/
if (t.isNumber()) {
final BigDecimal decimal = t.decimalValue();
try {
return decimal.toBigIntegerExact().hashCode();
} catch (ArithmeticException ignored) {
return decimal.stripTrailingZeros().hashCode();
}
}
// etc etc -- the rest works fine
이 순간에,이다, 최고의 내가 가지고 올 수 :
나는 순간에 가지고 올 수있는 최선은 이것이다.
해시 코드를 계산하는 더 좋은 방법이 있습니까?
(편집 : 등가 구현 here의 전체 코드)의 BigDecimal compareTo와 순서에 더블 더블의 해시 코드를 사용하는
@zsxwing : doEquivalent가 이미 오버라이드되었습니다. 편집을 참조하십시오. 전체 구현에 대한 링크를 추가했습니다. – fge
명확하지 않습니다. 코드가 동일한 값에 대해 동일한 해시 코드를 반환하지 않는 문제가 있습니까? 실수로 모든 고유 값에 대해 고유 한 해시 코드를 보장하려고합니까? –
"1", "1.0", "1.00"이 동일한 해시 코드를 반환하겠습니까? 어쩌면 hashCode를 사용하지 않는 TreeSet을 사용할 수 있습니까? – zsxwing