Adds support to BigDecimal in JsonPrimitive#equals - #2364
Conversation
Adds to the JsonPrimitive#equals the possibility to support BigDecimal
Adds test to check if the equals work with BigDecimals. Code snippet from issue google#904
| public void testBigDecimalEquals() { | ||
| JsonPrimitive small = new JsonPrimitive(1.0); | ||
| JsonPrimitive large = new JsonPrimitive(2.0); | ||
| assertThat(small.equals(large)).isFalse(); |
There was a problem hiding this comment.
This assert probably is overkill because is already tested here:
gson/gson/src/test/java/com/google/gson/JsonPrimitiveTest.java
Lines 246 to 250 in 3adead6
It's here to be consistent with the code in the issue #904
Replaces the `.equals` method with the `compareTo` in the `JsonPrimitive#equals` Change the ternary operator from `||` to `&&` so we are sure that both are `BigDecimal` Implements tests
Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
There was a problem hiding this comment.
@MaicolAntali, could you please merge main into your branch and fix the new Error Prone warning:
[WARNING] /gson/src/main/java/com/google/gson/JsonPrimitive.java:[294,47] [OperatorPrecedence] Use grouping parenthesis to make the operator precedence explicit
(see https://errorprone.info/bugpattern/OperatorPrecedence)
Did you mean 'return (this.value instanceof BigDecimal && other.value instanceof BigDecimal)'?
To me these changes look reasonable, and they should solve #904. I assume there might be some other cases where comparing BigDecimal with primitive values such as double or long might still cause precision loss, but if necessary that can be addressed later.
@eamonnmcmanus, what do you think?
- Extracts `thisAsDouble` & `otherAsDouble` variables to avoid double functions calls. - Adds a comment to improve the code readability.
|
@MaicolAntali, could you please merge |
|
Don't worry, help it's a pleasure! |
| // Uses compareTo to ignore scale of values, e.g. `0` and `0.00` should be considered equal | ||
| return this.getAsBigDecimal().compareTo(other.getAsBigDecimal()) == 0; |
There was a problem hiding this comment.
As side note / for future reference: I originally proposed using compareTo when this code was also comparing BigDecimal with non-BigDecimal, see #2364 (comment).
However, using compareTo instead of equals here has another advantage: It ensures JsonPrimitive.equals is transitive (as required by Object.equals), at least when wrapping a BigDecimal.
(
x equals yandy equals z) impliesx equals z
Now let
x = new JsonPrimitive(new BigDecimal("0"))y = new JsonPrimitive(0.0d)z = new JsonPrimitive(new BigDecimal("0.00"))
Using compareTo makes sure that equals is transitive. Whereas using BigDecimal.equals here would cause: x equals y and y equals z (because they fall back to double comparison), but x !equals z, which would not be transitive.
eamonnmcmanus
left a comment
There was a problem hiding this comment.
Thanks for doing this! I ran it against all of Google's internal tests and everything passed.
* Adds support to `BigDecimal` Adds to the JsonPrimitive#equals the possibility to support BigDecimal * Adds test Adds test to check if the equals work with BigDecimals. Code snippet from issue google#904 * Implements review comments Replaces the `.equals` method with the `compareTo` in the `JsonPrimitive#equals` Change the ternary operator from `||` to `&&` so we are sure that both are `BigDecimal` Implements tests * Changes to follow the google-style-guide * implements review comment Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com> * Fixes the `OperatorPrecedence` warn * Implements code improvements - Extracts `thisAsDouble` & `otherAsDouble` variables to avoid double functions calls. - Adds a comment to improve the code readability. * Implements `BigDecimal` check in the `JsonPrimitive.equals()` * Formats the code with `spotless:apply` --------- Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
Purpose
Fixes #904
Description
Currently a
BigDeciamalis cast to a double and this can give issue if the number doesn't fit in it.I have implemented a ternary operator to check if a number is a
BigDecimaland in that case use the properequalsmethod.Checklist
null@since $next-version$(
$next-version$is a special placeholder which is automatically replaced during release)TestCase)mvn clean verify javadoc:jarpasses without errors