私はJackson(バージョン2.1.x)に依存するJavaで書かれたJSONスキーマの実装を持っています。正確な理由から、私はJacksonに浮動小数点数にBigDecimal
を使用するよう指示します。"正規化" BigDecimalのハッシュコード:howto?
JSONスキーマのニーズには、特に必要なものがあります。数値のJSON値の等価は、数学的価値の等価性によって定義されます。例えば、これは法律上のスキーマ(enum
の値は一意である必要があります)ではない、ので、私はチェックのこの種のものが必要です。
{ "enum": [ 1, 1.0 ] }
しかし1
と1.0
ためJsonNodesは等しくありません。したがって、私はGuavaのの実装をコード化し、必要に応じて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