Fixed issue 147.

Integral values (byte, short, integer, long, BigInteger) are now comparable to each other.
Floating point values (float, double, BigDecimal) are now comparable to each other.
This commit is contained in:
Inderjeet Singh 2009-09-23 18:54:01 +00:00
parent 50eb582657
commit fdcd3945c5
2 changed files with 134 additions and 1 deletions

View File

@ -344,7 +344,19 @@ public final class JsonPrimitive extends JsonElement {
@Override
public int hashCode() {
return (value == null) ? 31 : value.hashCode();
if (value == null) {
return 31;
}
// Using recommended hashing algorithm from Effective Java for longs and doubles
if (isIntegral(this)) {
long value = getAsNumber().longValue();
return (int) (value ^ (value >>> 32));
}
if (isFloatingPoint(this)) {
long value = Double.doubleToLongBits(getAsNumber().doubleValue());
return (int) (value ^ (value >>> 32));
}
return value.hashCode();
}
@Override
@ -359,6 +371,36 @@ public final class JsonPrimitive extends JsonElement {
if (value == null) {
return other.value == null;
}
if (isIntegral(this) && isIntegral(other)) {
return getAsNumber().longValue() == other.getAsNumber().longValue();
}
if (isFloatingPoint(this) && isFloatingPoint(other)) {
return getAsNumber().doubleValue() == other.getAsNumber().doubleValue();
}
return value.equals(other.value);
}
/**
* Returns true if the specified number is an integral type
* (Long, Integer, Short, Byte, BigInteger)
*/
private static boolean isIntegral(JsonPrimitive primitive) {
if (primitive.value instanceof Number) {
Number number = (Number) primitive.value;
return number instanceof BigInteger || number instanceof Long || number instanceof Integer
|| number instanceof Short || number instanceof Byte;
}
return false;
}
/**
* Returns true if the specified number is a floating point type (BigDecimal, double, float)
*/
private static boolean isFloatingPoint(JsonPrimitive primitive) {
if (primitive.value instanceof Number) {
Number number = (Number) primitive.value;
return number instanceof BigDecimal || number instanceof Double || number instanceof Float;
}
return false;
}
}

View File

@ -81,6 +81,97 @@ public class JsonPrimitiveTest extends TestCase {
} catch (NumberFormatException expected) { }
}
public void testByteEqualsShort() {
JsonPrimitive p1 = new JsonPrimitive(new Byte((byte)10));
JsonPrimitive p2 = new JsonPrimitive(new Short((short)10));
assertEquals(p1, p2);
assertEquals(p1.hashCode(), p2.hashCode());
}
public void testByteEqualsInteger() {
JsonPrimitive p1 = new JsonPrimitive(new Byte((byte)10));
JsonPrimitive p2 = new JsonPrimitive(new Integer(10));
assertEquals(p1, p2);
assertEquals(p1.hashCode(), p2.hashCode());
}
public void testByteEqualsLong() {
JsonPrimitive p1 = new JsonPrimitive(new Byte((byte)10));
JsonPrimitive p2 = new JsonPrimitive(new Long(10L));
assertEquals(p1, p2);
assertEquals(p1.hashCode(), p2.hashCode());
}
public void testByteEqualsBigInteger() {
JsonPrimitive p1 = new JsonPrimitive(new Byte((byte)10));
JsonPrimitive p2 = new JsonPrimitive(new BigInteger("10"));
assertEquals(p1, p2);
assertEquals(p1.hashCode(), p2.hashCode());
}
public void testShortEqualsInteger() {
JsonPrimitive p1 = new JsonPrimitive(new Short((short)10));
JsonPrimitive p2 = new JsonPrimitive(new Integer(10));
assertEquals(p1, p2);
assertEquals(p1.hashCode(), p2.hashCode());
}
public void testShortEqualsLong() {
JsonPrimitive p1 = new JsonPrimitive(new Short((short)10));
JsonPrimitive p2 = new JsonPrimitive(new Long(10));
assertEquals(p1, p2);
assertEquals(p1.hashCode(), p2.hashCode());
}
public void testShortEqualsBigInteger() {
JsonPrimitive p1 = new JsonPrimitive(new Short((short)10));
JsonPrimitive p2 = new JsonPrimitive(new BigInteger("10"));
assertEquals(p1, p2);
assertEquals(p1.hashCode(), p2.hashCode());
}
public void testIntegerEqualsLong() {
JsonPrimitive p1 = new JsonPrimitive(new Integer(10));
JsonPrimitive p2 = new JsonPrimitive(new Long(10L));
assertEquals(p1, p2);
assertEquals(p1.hashCode(), p2.hashCode());
}
public void testIntegerEqualsBigInteger() {
JsonPrimitive p1 = new JsonPrimitive(new Integer(10));
JsonPrimitive p2 = new JsonPrimitive(new BigInteger("10"));
assertEquals(p1, p2);
assertEquals(p1.hashCode(), p2.hashCode());
}
public void testLongEqualsBigInteger() {
JsonPrimitive p1 = new JsonPrimitive(new Long(10L));
JsonPrimitive p2 = new JsonPrimitive(new BigInteger("10"));
assertEquals(p1, p2);
assertEquals(p1.hashCode(), p2.hashCode());
}
public void testFloatEqualsDouble() {
JsonPrimitive p1 = new JsonPrimitive(new Float(10.25F));
JsonPrimitive p2 = new JsonPrimitive(new Double(10.25D));
assertEquals(p1, p2);
assertEquals(p1.hashCode(), p2.hashCode());
}
public void testFloatEqualsBigDecimal() {
JsonPrimitive p1 = new JsonPrimitive(new Float(10.25F));
JsonPrimitive p2 = new JsonPrimitive(new BigDecimal("10.25"));
assertEquals(p1, p2);
assertEquals(p1.hashCode(), p2.hashCode());
}
public void testDoubleEqualsBigDecimal() {
JsonPrimitive p1 = new JsonPrimitive(new Double(10.25D));
JsonPrimitive p2 = new JsonPrimitive(new BigDecimal("10.25"));
assertEquals(p1, p2);
assertEquals(p1.hashCode(), p2.hashCode());
}
public void testValidJsonOnToString() throws Exception {
JsonPrimitive json = new JsonPrimitive("Some\nEscaped\nValue");
assertEquals("\"Some\\nEscaped\\nValue\"", json.toString());