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 BigDecimal
stałą BigDecimal.ZERO
pozwala uniknąć konstruowania new BigDecimal(0)
każdego wykonania.
FYI, BigDecimal
ma również stałe BigDecimal.ONE
i BigDecimal.TEN
dla 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
equals
i compareTo
nie 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 someValue
zmiennej, 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), .ZERO
to 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 != 0
dlatego wyobrażam sobie, że .equals()
bierze pod uwagę skalę. 0.00
daje precyzję setnym miejscu, a 0
nie jest tak precyzyjne. W zależności od sytuacji, z którą chcesz się trzymać .equals()
.
equals
i compareTo
nie jest takie, jak myślisz. docs.oracle.com/javase/1.5.0/docs/api/java/math/…
equals
bierze 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 selectPrice
jest null
.
equals
i compareTo
nie jest takie, jak myślisz. docs.oracle.com/javase/1.5.0/docs/api/java/math/…