Java'da yazılmış bir JSON Şema uygulaması var, bu da Jackson (sürüm 2.1.x). Kesinlik nedeniyle, Jackson'a kayan noktalı sayılar için BigDecimal
kullanmasını söylüyorum.BigDecimal hash kodu "Normalleştiriliyor": Howto?
JSON Şeması'nın gereksinimleri için, belirli bir gereksinim vardır: JSON değeri eşitliği, sayısal değerler için, matematik değerlerinin eşitliği ile tanımlanır.
{ "enum": [ 1, 1.0 ] }
Ama JsonNodes 1
ve 1.0
için eşit değildir: Örneğin, bu yasal bir şema (bir enum
değerler benzersiz olmalıdır) değil, çünkü ben çek bu tür gerekiyor. Bu nedenle, Guava'nın Equivalence bir uygulamasını kodluyorum ve uygun olduğunda Set<Equivalence.Wrapper<JsonNode>>
kullanın. Ve bu uygulama sadece sayısal düğümler değil, tüm düğüm türleri için çalışmalıdır.
Ve bu uygulamanın en zor kısmı sayısal düğümler için doHash()
olarak çıkıyor:/onlar tamsayı veya kayan noktalı sayılar olsun, eşdeğer matematiksel değerler için aynı karma kodunun gerekir.
@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
Bu anda, olup, en iyi ben ile gelebilir:
şu anda birlikte gelen en iyi budur.
Böyle bir hashcode hesaplamak için daha iyi bir yolu var mı?
(düzenleme: Denklik uygulanması here tam kodu) BigDecimal compareTo sipariş üzerine katlayın ve Çift Kişilik en hashCode kullanmak
@zsxwing: doEquivalent zaten geçersizdir - bkz. Düzenle, Uygulamanın tamamına bir bağlantı ekledim – fge
Net değil - kodun eşit değerler için eşit karma kodları döndürmediği bir sorun var mı, yoksa yanlışlıkla) her bir farklı değer için benzersiz bir karma kodu sağlamaya çalışıyor musunuz? –
Bunu "1", "1.0", "1.00" aynı karma kodu geri döndürmek ister misiniz? Belki hashCode kullanmayan TreeSet'i kullanabilirsiniz? – zsxwing