Tengo el siguiente código en Java;
BigDecimal price; // assigned elsewhere
if (price.compareTo(new BigDecimal("0.00")) == 0) {
return true;
}
¿Cuál es la mejor manera de escribir la condición if?
Tengo el siguiente código en Java;
BigDecimal price; // assigned elsewhere
if (price.compareTo(new BigDecimal("0.00")) == 0) {
return true;
}
¿Cuál es la mejor manera de escribir la condición if?
Respuestas:
Usar en compareTo(BigDecimal.ZERO)
lugar de equals()
:
if (price.compareTo(BigDecimal.ZERO) == 0) // see below
La comparación con la BigDecimal
constante BigDecimal.ZERO
evita tener que construir new BigDecimal(0)
cada ejecución.
Para su información, BigDecimal
también tiene constantes BigDecimal.ONE
y BigDecimal.TEN
para su conveniencia.
La razón por la que no puede usar BigDecimal#equals()
es que tiene en cuenta la escala :
new BigDecimal("0").equals(BigDecimal.ZERO) // true
new BigDecimal("0.00").equals(BigDecimal.ZERO) // false!
por lo tanto, no es adecuado para una comparación puramente numérica. Sin embargo, BigDecimal.compareTo()
no considera la escala al comparar:
new BigDecimal("0").compareTo(BigDecimal.ZERO) == 0 // true
new BigDecimal("0.00").compareTo(BigDecimal.ZERO) == 0 // true
Alternativamente, se puede usar signum () :
if (price.signum() == 0) {
return true;
}
BigDecimal.ZERO.compareTo(null)
lanzará NPE
Hay una constante con la que puede verificar:
someBigDecimal.compareTo(BigDecimal.ZERO) == 0
equals
y compareTo
no es como piensas. docs.oracle.com/javase/1.5.0/docs/api/java/math/…
Alternativamente, creo que vale la pena mencionar que el comportamiento de los métodos equals y compareTo en la clase BigDecimal no son consistentes entre sí .
Esto básicamente significa que:
BigDecimal someValue = new BigDecimal("0.00");
System.out.println(someValue.compareTo(BigDecimal.ZERO)==0); //true
System.out.println(someValue.equals(BigDecimal.ZERO)); //false
Por lo tanto, debe tener mucho cuidado con la escala en su someValue
variable, de lo contrario obtendría un resultado inesperado.
Debería usar equals () ya que son objetos y utilizar la instancia CERO incorporada:
if(selectPrice.equals(BigDecimal.ZERO))
Tenga .equals()
en cuenta que tiene en cuenta la escala, por lo que, a menos que selectPrice sea la misma escala (0) que.ZERO
esto devolverá falso.
Para eliminar la escala de la ecuación, por así decirlo:
if(selectPrice.compareTo(BigDecimal.ZERO) == 0)
Debo señalar que para ciertas situaciones matemáticas, 0.00 != 0
es por eso que imagino que .equals()
toma en cuenta la escala. 0.00
da precisión al lugar de las centésimas, mientras 0
que no es tan preciso. Dependiendo de la situación con la que quiera quedarse .equals()
.
equals
y compareTo
no es como piensas. docs.oracle.com/javase/1.5.0/docs/api/java/math/…
equals
tiene en cuenta la escala, que no es lo que queremos aquí.
equals
debería usarse en lugar de compareTo()
. El OP no especifica qué tipo de matemática está usando, por lo que tiene razón, es mejor darle ambas opciones.
GriffeyDog es definitivamente correcto:
Código:
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)));
Resultados:
myBigDecimal=0.000000
BigDecimal.valueOf(0.000000)=0.0
equals=false
compare=true
Si bien entiendo las ventajas de la comparación BigDecimal, no lo consideraría una construcción intuitiva (como los operadores ==, <,>, <=,> =). Cuando tienes un millón de cosas (bueno, siete cosas) en tu cabeza, cualquier cosa que puedas reducir tu carga cognitiva es algo bueno. Así que construí algunas funciones útiles de conveniencia:
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);
}
Aquí está cómo usarlos:
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));
Los resultados se ven así:
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"));
Hay una constante estática que representa 0 :
BigDecimal.ZERO.equals(selectPrice)
Deberías hacer esto en lugar de:
selectPrice.equals(BigDecimal.ZERO)
para evitar el caso donde selectPrice
está null
.
equals
y compareTo
no es como piensas. docs.oracle.com/javase/1.5.0/docs/api/java/math/…