Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Null Safe Compare two bigdecimal objects having 0.0 and 0

Initially code was :

            if(!Objects.equals(src.getApplicationItemCost(), dest.getApplicationItemCost())){
               log.info("Difference")
            }

Output:

      getApplicationItemCost: src:0.0| dest:0
      Difference

ApplicationItemCost is of type BigDecimal.

If I use compareTo then I have to explicitly check nulls like :

LOG.info("getApplicationItemCost: src:" + src.getApplicationItemCost() + "| dest:" + dest.getApplicationItemCost());
        if((src.getApplicationItemCost()==null && dest.getApplicationItemCost()!=null)
                || (src.getApplicationItemCost()!=null && dest.getApplicationItemCost()==null)
                || !Objects.equals(src.getApplicationItemCost(), dest.getApplicationItemCost())
                || src.getApplicationItemCost().compareTo(dest.getApplicationItemCost())!=0 )

Any suggestion to compare 0.0 and 0. Why is this difference? (May be database has Number field and when converted to big decimal it does not show 0.0?)

like image 718
fatherazrael Avatar asked Feb 12 '20 06:02

fatherazrael


People also ask

How does BigDecimal value compare with zero?

Using the compareTo Method Two BigDecimal objects that are equal in value but have a different scale (like 2.0 and 2.00) are considered equal by this method. Therefore, we can check BigDecimal. ZERO. compareTo(givenBdNumber) == 0 to decide if givenBdNumber has the value zero.

Can BigDecimal have null value?

You either never allow null values in database, application or view and initialize everything with new BigDecimal(0) or perform null checks on every usage for nullable values.

How do you know if two BigDecimal values are equal?

equals() method compares this BigDecimal with the specified Object for equality. Unlike compareTo, this method considers two BigDecimal objects equal only if they are equal in value and scale (thus 2.0 is not equal to 2.00 when compared by this method).


3 Answers

Build a comparator:

Comparator<BigDecimal> c = Comparator.nullsFirst(Comparator.naturalOrder());

(Or nullsLast, it doesn't matter if you're only ever comparing to zero).

Then:

if (c.compare(first, second) != 0) {
  // ...
}
like image 65
Andy Turner Avatar answered Oct 20 '22 12:10

Andy Turner


Try using

CompareToBuilder

class provided by

org.apache.commons.lang3

as it make null safe comparison. Sample code is:

public static <T, U> int nullSafeComparison(T t, U u) {
        return new CompareToBuilder().append(t, u).toComparison();
    }

public static void main(String[] args) {
        BigDecimal zero = BigDecimal.ZERO;
        BigDecimal zeroPzero = new BigDecimal("0.0");

        System.out.println( zero + " " + zeroPzero);

        System.out.println(nullSafeComparison(zero, zeroPzero));
    }

If both numbers are same it will return 0, if 1st is greater than 2nd the result will be 1 and -1 if 1st number is less than 2nd.

like image 27
oOXAam Avatar answered Oct 20 '22 11:10

oOXAam


Custom BigDecimal null safe Comparison (without any exteranal library):

{
    BigDecimal big1, big2; 

    big1 = new BigDecimal(0); 
    big2 = new BigDecimal(0.0); 

    int compareResult1 = compareTo(b1,null);
    int compareResult2 = compareTo(null,b2);
}

public static <T extends Comparable<T>> int compareTo(final T c1, final T c2) {
    final boolean f1, f2;
    return (f1 = c1 == null) ^ (f2 = c2 == null) ? f1 ? -1 : 1 : f1 && f2 ? 0 : c1.compareTo(c2);
}
like image 23
Suryakant Bharti Avatar answered Oct 20 '22 12:10

Suryakant Bharti