[ 
https://issues.apache.org/jira/browse/LANG-1665?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17385493#comment-17385493
 ] 

Alex Herbert commented on LANG-1665:
------------------------------------

This issue is related to the BigDecimal equals method only returning true to 
binary equality. The same issue arises for Double or Float where there are two 
representations of zero:
{code:java}
Double d1 = Double.valueOf(-0.0);
Double d2 = Double.valueOf(0.0);
assert d1.equals(d2) == false;
Float f1 = Float.valueOf(-0.0f);
Float f2 = Float.valueOf(0.0f);
assert f1.equals(f2) == false;
{code}
I am not aware of other objects that can have a comparison that is 0 but not be 
equal. This applies to Numbers. I would suggest expanding the method to cover 
these cases of 
 numbers. The two objects can be checked if they are instances of a Number. If 
true then compare them as a number:
{code:java}
public static boolean equalsOrCompareNumber(final Object object1, final Object 
object2) {
  if (object1 instanceof Number && object2 instanceof Number) {
    // Handle BigDecimal
    if (object1 instanceof BigDecimal) {
      if (object2 instanceof BigDecimal) {
        return ((BigDecimal) object1).compareTo((BigDecimal) object2) == 0;
      }
      return false;
    }
    // Handle two floating-point representations of zero: -0.0 and 0.0
    // This applies to Double or Float.
    if (((Number) object1).doubleValue() == 0) {
      // Must be the same class
      return object1.getClass().equals(object2.getClass()) &&
             ((Number) object2).doubleValue() == 0;
    }
    // No requirement for null check in Objects.equals
    return object1.equals(object2);
  }
  return Objects.equals(object1, object2);
}
{code}
This would not return true for two numbers that have the same value but are 
instances of different classes. The method could be updated to do this if 
required. But it cannot just use doubleValue() as this will not cover all cases 
such a long integers or BigIntegers.

> Modify Tuple equals to take BigDecimal comparison
> -------------------------------------------------
>
>                 Key: LANG-1665
>                 URL: https://issues.apache.org/jira/browse/LANG-1665
>             Project: Commons Lang
>          Issue Type: Improvement
>          Components: lang.tuple.*
>    Affects Versions: 3.12.0
>            Reporter: Chikashi Toyoshima
>            Priority: Trivial
>             Fix For: 3.12.0
>
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> I understand that this would be a bit controversial. Imhp as possibly 
> ignorable suggestion, it'd be more helpful if the Tuple supports BgDecimal 
> numeric equality rather than simply checking object.
>  
> In a particular case, you may want to check if a collection of pairs contain 
> a certain pair which includes BigDecimal values. Then to check object 
> equality is maybe just right or not. But in many cases, I assume that numeric 
> comparison would be more demanded such as following simple example. 
> {code:java}
> Set<Pair<String, BigDecimal>> someCollection = getPairs(); 
> someCollection.contains(Pair.of("foo", BigDecimal.valueOf(100))); 
> {code}
>  
> I created the PR. Please take a look. I'm happy to whichever it is accepted 
> or not receiving feedback.
> [https://github.com/apache/commons-lang/pull/780]



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to