¿Cómo verificar si la variable BigDecimal == 0 en java?

202

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?

JoJo
fuente
12
Muchas respuestas sugieren utilizar el método .equals () de BigDecimal. Pero ese método tiene en cuenta la escala, por lo que no es equivalente a usar compareTo ().
GriffeyDog

Respuestas:

474

Usar en compareTo(BigDecimal.ZERO)lugar de equals():

if (price.compareTo(BigDecimal.ZERO) == 0) // see below

La comparación con la BigDecimalconstante BigDecimal.ZEROevita tener que construir new BigDecimal(0)cada ejecución.

Para su información, BigDecimaltambién tiene constantes BigDecimal.ONEy BigDecimal.TENpara su conveniencia.


¡Nota!

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
Bohemio
fuente
BigDecimal.ZERO.compareTo (price) == 0
Jackkobec
97

Alternativamente, se puede usar signum () :

if (price.signum() == 0) {
    return true;
}
kman
fuente
21
Tal vez sea más rápido, pero compareTo (BigDecimal.ZERO) es más legible.
ElYeante
@ElYeante, siempre puede envolver esto con un método, que tenga un nombre más legible, o incluso describa parte de su lógica empresarial, relacionada con dicha comparación
WeGa
3
Desafortunadamente signum () no es nulo-seguro, mientras que compareTo lo es, cuando se compara como BigDecimal.ZERO.compareTo (), así que presta atención a eso
WeGa
15
@WeGa Eso no es cierto: BigDecimal.ZERO.compareTo(null)lanzará NPE
ACV el
55
@ACV, gracias por tu vigilancia. Visto el código fuente, compareTo () solo espera un argumento no nulo.
WeGa
24

Hay una constante con la que puede verificar:

someBigDecimal.compareTo(BigDecimal.ZERO) == 0
pablochan
fuente
3
Permiso para robar su terminología de una "condición de Yoda" solicitada.
SimplyPanda
3
Esto es fantastico .
SimplyPanda
El comportamiento de Java BigDecimal de equalsy compareTono es como piensas. docs.oracle.com/javase/1.5.0/docs/api/java/math/…
nhahtdh
2
CompareTo de BigDecimal aún arrojará una excepción si pasa un valor nulo.
John Jiang
5

Usualmente uso lo siguiente:

if (selectPrice.compareTo(BigDecimal.ZERO) == 0) { ... }
gpol
fuente
5

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 someValuevariable, de lo contrario obtendría un resultado inesperado.

Edwin Dalorzo
fuente
5

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 != 0es por eso que imagino que .equals()toma en cuenta la escala. 0.00da precisión al lugar de las centésimas, mientras 0que no es tan preciso. Dependiendo de la situación con la que quiera quedarse .equals().

NominSim
fuente
El comportamiento de Java BigDecimal de equalsy compareTono es como piensas. docs.oracle.com/javase/1.5.0/docs/api/java/math/…
nhahtdh
¿Te importaría explicar a qué te refieres en lugar de vincular a los documentos? Lo que sugerí debería funcionar para el OP.
NominSim
La respuesta de Edwin Dalorzo lo explica bastante bien, en realidad. equalstiene en cuenta la escala, que no es lo que queremos aquí.
nhahtdh
@nhahtdh Gracias por la información, de hecho, aunque hay situaciones en las que 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.
NominSim
3

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
Tihamer
fuente
1
Hay múltiples respuestas que explican exactamente eso. ¿Cuál es el punto de agregar otra respuesta? Si tiene información adicional, es una buena idea agregar una nueva respuesta, pero este no es el caso en esta publicación.
Tom
Punto a favor. Sin embargo, cuando estoy aprendiendo algo, me gusta ver tantos ejemplos como sea posible, incluso si son similares. Para ti, Tom, agregué mi biblioteca que me pareció útil. Tu kilometraje puede variar. :-)
Tihamer
0

Solo quiero compartir aquí algunas extensiones útiles para kotlin

fun BigDecimal.isZero() = compareTo(BigDecimal.ZERO) == 0
fun BigDecimal.isOne() = compareTo(BigDecimal.ONE) == 0
fun BigDecimal.isTen() = compareTo(BigDecimal.TEN) == 0
Nokuap
fuente
-2
BigDecimal.ZERO.setScale(2).equals(new BigDecimal("0.00"));
DongHoon Kim
fuente
1
Si bien este código puede responder la pregunta, proporcionar un contexto adicional con respecto a cómo y / o por qué resuelve el problema mejoraría el valor a largo plazo de la respuesta. ¡Recuerde que está respondiendo la pregunta para los lectores en el futuro, no solo la persona que pregunta ahora! Por favor, editar su respuesta a añadir una explicación, y dar una indicación de lo que se aplican limitaciones y supuestos. Tampoco hace daño mencionar por qué esta respuesta es más apropiada que otras.
Dev-iL
-8

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.

tskuzzy
fuente
3
El comportamiento de Java BigDecimal de equalsy compareTono es como piensas. docs.oracle.com/javase/1.5.0/docs/api/java/math/…
nhahtdh
así que para la segunda línea ... si se seleccionaPrecio es nulo, entonces arrojará NullPointerException.
user3206236