Mam następujący kod w Javie;
BigDecimal price; // assigned elsewhere
if (price.compareTo(new BigDecimal("0.00")) == 0) {
return true;
}
Jaki jest najlepszy sposób na napisanie warunku if?
Mam następujący kod w Javie;
BigDecimal price; // assigned elsewhere
if (price.compareTo(new BigDecimal("0.00")) == 0) {
return true;
}
Jaki jest najlepszy sposób na napisanie warunku if?
Odpowiedzi:
Użyj compareTo(BigDecimal.ZERO)zamiast equals():
if (price.compareTo(BigDecimal.ZERO) == 0) // see below
Porównanie ze BigDecimalstałą BigDecimal.ZEROpozwala uniknąć konstruowania new BigDecimal(0)każdego wykonania.
FYI, BigDecimalma również stałe BigDecimal.ONEi BigDecimal.TENdla Twojej wygody.
Nie możesz używać BigDecimal#equals(), ponieważ bierze pod uwagę skalę :
new BigDecimal("0").equals(BigDecimal.ZERO) // true
new BigDecimal("0.00").equals(BigDecimal.ZERO) // false!
więc nie nadaje się do czysto numerycznego porównania. Jednak BigDecimal.compareTo()nie uwzględnia skali przy porównywaniu:
new BigDecimal("0").compareTo(BigDecimal.ZERO) == 0 // true
new BigDecimal("0.00").compareTo(BigDecimal.ZERO) == 0 // true
Alternatywnie można użyć signum () :
if (price.signum() == 0) {
return true;
}
BigDecimal.ZERO.compareTo(null)rzuci NPE
Istnieje stała, którą możesz sprawdzić w stosunku do:
someBigDecimal.compareTo(BigDecimal.ZERO) == 0
equalsi compareTonie jest takie, jak myślisz. docs.oracle.com/javase/1.5.0/docs/api/java/math/…
Alternatywnie, myślę, że warto wspomnieć, że zachowanie metod równości i metod porównywania w klasie BigDecimal nie jest ze sobą zgodne .
Zasadniczo oznacza to, że:
BigDecimal someValue = new BigDecimal("0.00");
System.out.println(someValue.compareTo(BigDecimal.ZERO)==0); //true
System.out.println(someValue.equals(BigDecimal.ZERO)); //false
Dlatego musisz bardzo uważać na skalę w someValuezmiennej, w przeciwnym razie uzyskasz nieoczekiwany wynik.
Chciałbyś użyć equals (), ponieważ są obiektami, i użyć wbudowanej instancji ZERO:
if(selectPrice.equals(BigDecimal.ZERO))
Zauważ, że .equals()bierze się pod uwagę skalę, więc jeśli selectPrice jest tej samej skali (0), .ZEROto wtedy zwróci false.
Aby wyjąć skalę z równania:
if(selectPrice.compareTo(BigDecimal.ZERO) == 0)
Powinienem zauważyć, że w niektórych sytuacjach matematycznych, 0.00 != 0dlatego wyobrażam sobie, że .equals()bierze pod uwagę skalę. 0.00daje precyzję setnym miejscu, a 0nie jest tak precyzyjne. W zależności od sytuacji, z którą chcesz się trzymać .equals().
equalsi compareTonie jest takie, jak myślisz. docs.oracle.com/javase/1.5.0/docs/api/java/math/…
equalsbierze pod uwagę skalę, której nie chcemy tutaj.
equals należy użyć zamiast compareTo(). OP nie określa, jakiego rodzaju matematyki używa, więc masz rację, lepiej dać mu obie opcje.
GriffeyDog jest zdecydowanie poprawny:
Kod:
BigDecimal myBigDecimal = new BigDecimal("00000000.000000");
System.out.println("bestPriceBigDecimal=" + myBigDecimal);
System.out.println("BigDecimal.valueOf(0.000000)=" + BigDecimal.valueOf(0.000000));
System.out.println(" equals=" + myBigDecimal.equals(BigDecimal.ZERO));
System.out.println("compare=" + (0 == myBigDecimal.compareTo(BigDecimal.ZERO)));
Wyniki:
myBigDecimal=0.000000
BigDecimal.valueOf(0.000000)=0.0
equals=false
compare=true
Chociaż rozumiem zalety porównania BigDecimal, nie uważałbym go za intuicyjną konstrukcję (podobnie jak operatory ==, <,>, <=,> =). Kiedy trzymasz w głowie milion rzeczy (ok, siedem rzeczy), wtedy wszystko, co możesz zmniejszyć obciążenie poznawcze, jest dobrą rzeczą. Zbudowałem więc kilka użytecznych funkcji:
public static boolean equalsZero(BigDecimal x) {
return (0 == x.compareTo(BigDecimal.ZERO));
}
public static boolean equals(BigDecimal x, BigDecimal y) {
return (0 == x.compareTo(y));
}
public static boolean lessThan(BigDecimal x, BigDecimal y) {
return (-1 == x.compareTo(y));
}
public static boolean lessThanOrEquals(BigDecimal x, BigDecimal y) {
return (x.compareTo(y) <= 0);
}
public static boolean greaterThan(BigDecimal x, BigDecimal y) {
return (1 == x.compareTo(y));
}
public static boolean greaterThanOrEquals(BigDecimal x, BigDecimal y) {
return (x.compareTo(y) >= 0);
}
Oto jak z nich korzystać:
System.out.println("Starting main Utils");
BigDecimal bigDecimal0 = new BigDecimal(00000.00);
BigDecimal bigDecimal2 = new BigDecimal(2);
BigDecimal bigDecimal4 = new BigDecimal(4);
BigDecimal bigDecimal20 = new BigDecimal(2.000);
System.out.println("Positive cases:");
System.out.println("bigDecimal0=" + bigDecimal0 + " == zero is " + Utils.equalsZero(bigDecimal0));
System.out.println("bigDecimal2=" + bigDecimal2 + " < bigDecimal4=" + bigDecimal4 + " is " + Utils.lessThan(bigDecimal2, bigDecimal4));
System.out.println("bigDecimal2=" + bigDecimal2 + " == bigDecimal20=" + bigDecimal20 + " is " + Utils.equals(bigDecimal2, bigDecimal20));
System.out.println("bigDecimal2=" + bigDecimal2 + " <= bigDecimal20=" + bigDecimal20 + " is " + Utils.equals(bigDecimal2, bigDecimal20));
System.out.println("bigDecimal2=" + bigDecimal2 + " <= bigDecimal4=" + bigDecimal4 + " is " + Utils.lessThanOrEquals(bigDecimal2, bigDecimal4));
System.out.println("bigDecimal4=" + bigDecimal4 + " > bigDecimal2=" + bigDecimal2 + " is " + Utils.greaterThan(bigDecimal4, bigDecimal2));
System.out.println("bigDecimal4=" + bigDecimal4 + " >= bigDecimal2=" + bigDecimal2 + " is " + Utils.greaterThanOrEquals(bigDecimal4, bigDecimal2));
System.out.println("bigDecimal2=" + bigDecimal2 + " >= bigDecimal20=" + bigDecimal20 + " is " + Utils.greaterThanOrEquals(bigDecimal2, bigDecimal20));
System.out.println("Negative cases:");
System.out.println("bigDecimal2=" + bigDecimal2 + " == zero is " + Utils.equalsZero(bigDecimal2));
System.out.println("bigDecimal2=" + bigDecimal2 + " == bigDecimal4=" + bigDecimal4 + " is " + Utils.equals(bigDecimal2, bigDecimal4));
System.out.println("bigDecimal4=" + bigDecimal4 + " < bigDecimal2=" + bigDecimal2 + " is " + Utils.lessThan(bigDecimal4, bigDecimal2));
System.out.println("bigDecimal4=" + bigDecimal4 + " <= bigDecimal2=" + bigDecimal2 + " is " + Utils.lessThanOrEquals(bigDecimal4, bigDecimal2));
System.out.println("bigDecimal2=" + bigDecimal2 + " > bigDecimal4=" + bigDecimal4 + " is " + Utils.greaterThan(bigDecimal2, bigDecimal4));
System.out.println("bigDecimal2=" + bigDecimal2 + " >= bigDecimal4=" + bigDecimal4 + " is " + Utils.greaterThanOrEquals(bigDecimal2, bigDecimal4));
Wyniki wyglądają następująco:
Positive cases:
bigDecimal0=0 == zero is true
bigDecimal2=2 < bigDecimal4=4 is true
bigDecimal2=2 == bigDecimal20=2 is true
bigDecimal2=2 <= bigDecimal20=2 is true
bigDecimal2=2 <= bigDecimal4=4 is true
bigDecimal4=4 > bigDecimal2=2 is true
bigDecimal4=4 >= bigDecimal2=2 is true
bigDecimal2=2 >= bigDecimal20=2 is true
Negative cases:
bigDecimal2=2 == zero is false
bigDecimal2=2 == bigDecimal4=4 is false
bigDecimal4=4 < bigDecimal2=2 is false
bigDecimal4=4 <= bigDecimal2=2 is false
bigDecimal2=2 > bigDecimal4=4 is false
bigDecimal2=2 >= bigDecimal4=4 is false
BigDecimal.ZERO.setScale(2).equals(new BigDecimal("0.00"));
Istnieje stała statyczna reprezentująca 0 :
BigDecimal.ZERO.equals(selectPrice)
Powinieneś to zrobić zamiast:
selectPrice.equals(BigDecimal.ZERO)
w celu uniknięcia przypadku, w którym selectPricejest null.
equalsi compareTonie jest takie, jak myślisz. docs.oracle.com/javase/1.5.0/docs/api/java/math/…