From 1b8244e28f75f2ef49fb5ffa8fb69c9c9838f858 Mon Sep 17 00:00:00 2001 From: Francis Galiegue Date: Mon, 7 Apr 2014 07:13:03 +0200 Subject: [PATCH] Ensure that DecimalNodes with mathematically equal values are equal And also ensure that .hashCode() works as well. For the latter, pick the hashCode() of the underlying BigDecimal's double value. See also here: http://stackoverflow.com/a/14313302/1093528 --- .../jackson/databind/node/DecimalNode.java | 4 +-- .../databind/node/TestNumberNodes.java | 27 +++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/fasterxml/jackson/databind/node/DecimalNode.java b/src/main/java/com/fasterxml/jackson/databind/node/DecimalNode.java index fd5d1a1ee6..578a7e7beb 100644 --- a/src/main/java/com/fasterxml/jackson/databind/node/DecimalNode.java +++ b/src/main/java/com/fasterxml/jackson/databind/node/DecimalNode.java @@ -116,11 +116,11 @@ public boolean equals(Object o) if (o == this) return true; if (o == null) return false; if (o instanceof DecimalNode) { - return ((DecimalNode) o)._value.equals(_value); + return ((DecimalNode) o)._value.compareTo(_value) == 0; } return false; } @Override - public int hashCode() { return _value.hashCode(); } + public int hashCode() { return Double.valueOf(doubleValue()).hashCode(); } } diff --git a/src/test/java/com/fasterxml/jackson/databind/node/TestNumberNodes.java b/src/test/java/com/fasterxml/jackson/databind/node/TestNumberNodes.java index ca199d4a36..73e4216273 100644 --- a/src/test/java/com/fasterxml/jackson/databind/node/TestNumberNodes.java +++ b/src/test/java/com/fasterxml/jackson/databind/node/TestNumberNodes.java @@ -184,6 +184,33 @@ public void testDecimalNode() throws Exception assertTrue(DecimalNode.valueOf(BigDecimal.valueOf(Long.MIN_VALUE)).canConvertToLong()); } + public void testDecimalNodeEqualsHashCode() + { + /* + * We want DecimalNodes with equivalent _numeric_ values to be equal; + * this is not the case for BigDecimal where "1.0" and "1" are not + * equal! + */ + BigDecimal b1 = BigDecimal.ONE; + BigDecimal b2 = new BigDecimal("1.0"); + BigDecimal b3 = new BigDecimal("0.01e2"); + BigDecimal b4 = new BigDecimal("1000e-3"); + + DecimalNode node1 = new DecimalNode(b1); + DecimalNode node2 = new DecimalNode(b2); + DecimalNode node3 = new DecimalNode(b3); + DecimalNode node4 = new DecimalNode(b4); + + assertEquals(node1.hashCode(), node2.hashCode()); + assertEquals(node2.hashCode(), node3.hashCode()); + assertEquals(node3.hashCode(), node4.hashCode()); + + assertEquals(node1, node2); + assertEquals(node2, node1); + assertEquals(node2, node3); + assertEquals(node3, node4); + } + public void testBigIntegerNode() throws Exception { BigIntegerNode n = BigIntegerNode.valueOf(BigInteger.ONE);