У меня есть следующий код на Java;
BigDecimal price; // assigned elsewhere
if (price.compareTo(new BigDecimal("0.00")) == 0) {
return true;
}
Как лучше написать условие if?
У меня есть следующий код на Java;
BigDecimal price; // assigned elsewhere
if (price.compareTo(new BigDecimal("0.00")) == 0) {
return true;
}
Как лучше написать условие if?
Ответы:
Используйте compareTo(BigDecimal.ZERO)вместо equals():
if (price.compareTo(BigDecimal.ZERO) == 0) // see below
Сравнение с BigDecimalконстантой BigDecimal.ZEROпозволяет избежать необходимости создавать new BigDecimal(0)каждое выполнение.
К вашему сведению, BigDecimalтакже есть константы BigDecimal.ONEи BigDecimal.TENдля вашего удобства.
Причина, по которой вы не можете использовать BigDecimal#equals()это то, что учитывает масштаб :
new BigDecimal("0").equals(BigDecimal.ZERO) // true
new BigDecimal("0.00").equals(BigDecimal.ZERO) // false!
поэтому он не подходит для чисто числового сравнения. Тем BigDecimal.compareTo()не менее, не учитывает масштаб при сравнении:
new BigDecimal("0").compareTo(BigDecimal.ZERO) == 0 // true
new BigDecimal("0.00").compareTo(BigDecimal.ZERO) == 0 // true
В качестве альтернативы, signum () можно использовать:
if (price.signum() == 0) {
return true;
}
BigDecimal.ZERO.compareTo(null)бросит NPE
Существует константа, с которой вы можете проверить:
someBigDecimal.compareTo(BigDecimal.ZERO) == 0
equalsи compareToне так, как вы думаете. docs.oracle.com/javase/1.5.0/docs/api/java/math/…
В качестве альтернативы, я думаю, стоит упомянуть, что поведение методов equals и compareTo в классе BigDecimal не соответствуют друг другу .
Это в основном означает, что:
BigDecimal someValue = new BigDecimal("0.00");
System.out.println(someValue.compareTo(BigDecimal.ZERO)==0); //true
System.out.println(someValue.equals(BigDecimal.ZERO)); //false
Поэтому вы должны быть очень осторожны со шкалой в вашей someValueпеременной, иначе вы получите неожиданный результат.
Вы хотели бы использовать equals (), так как они являются объектами, и использовать встроенный экземпляр ZERO:
if(selectPrice.equals(BigDecimal.ZERO))
Обратите внимание, что .equals()учитывается масштаб, поэтому, если selectPrice не имеет такой же масштаб (0), как .ZEROтогда, он вернет false.
Чтобы вывести масштаб из уравнения как бы:
if(selectPrice.compareTo(BigDecimal.ZERO) == 0)
Я должен отметить, что для определенных математических ситуаций 0.00 != 0, поэтому я предполагаю, что .equals()учитывает масштаб. 0.00дает точность до сотого места, а 0не так точно. В зависимости от ситуации вы можете придерживаться .equals().
equalsи compareToне так, как вы думаете. docs.oracle.com/javase/1.5.0/docs/api/java/math/…
equalsучитывает масштаб, а это не то, что мы хотим здесь.
equals следует использовать вместо compareTo(). ОП не указывает, какой тип математики он использует, поэтому вы правы, лучше дать ему оба варианта.
GriffeyDog определенно прав:
Код:
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)));
Полученные результаты:
myBigDecimal=0.000000
BigDecimal.valueOf(0.000000)=0.0
equals=false
compare=true
Хотя я понимаю преимущества сравнения BigDecimal, я бы не стал рассматривать его как интуитивную конструкцию (как это делают операторы ==, <,>, <=,> =). Когда вы держите в своей голове миллион вещей (хорошо, семь вещей), тогда все, что вы можете уменьшить когнитивную нагрузку, - это хорошо. Поэтому я построил несколько полезных вспомогательных функций:
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);
}
Вот как их использовать:
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));
Результаты выглядят так:
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"));
Есть статическая константа, которая представляет 0 :
BigDecimal.ZERO.equals(selectPrice)
Вы должны сделать это вместо:
selectPrice.equals(BigDecimal.ZERO)
во избежание того случая, когда selectPriceесть null.
equalsи compareToне так, как вы думаете. docs.oracle.com/javase/1.5.0/docs/api/java/math/…