我有一个用 Java 编写的 JSON Schema 实现,它依赖于Jackson(版本 2.1.x)。出于准确性的原因,我告诉杰克逊使用BigDecimal
浮点数。
对于 JSON Schema 的需求,有一个特殊的需求:JSON 值相等,对于数值,是通过它们的数学值相等来定义的。我需要这种检查,例如,这不是一个合法的模式(an 中的值enum
应该是唯一的):
{ "enum": [ 1, 1.0 ] }
但是 JsonNodes for 1
and1.0
是不相等的。因此,我编写了 Guava's 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
目前,这是我能想到的最好的。
有没有更好的方法来计算这样的哈希码?
(编辑:此处等效实现的完整代码)