Como verificar se a variável BigDecimal == 0 em java?

202

Eu tenho o seguinte código em Java;

BigDecimal price; // assigned elsewhere

if (price.compareTo(new BigDecimal("0.00")) == 0) {
    return true;
}

Qual é a melhor maneira de escrever a condição if?

JoJo
fonte
12
Muitas respostas estão sugerindo o uso do método .equals () de BigDecimal. Mas esse método leva em consideração a escala, portanto não é equivalente ao uso de compareTo ().
GriffeyDog

Respostas:

472

Use em compareTo(BigDecimal.ZERO)vez de equals():

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

Comparando com a BigDecimalconstante BigDecimal.ZEROevita ter que construir new BigDecimal(0)cada execução.

Para sua informação, BigDecimaltambém tem constantes BigDecimal.ONEe BigDecimal.TENpara sua conveniência.


Nota!

A razão pela qual você não pode usar BigDecimal#equals()é que ela leva em consideração a escala :

new BigDecimal("0").equals(BigDecimal.ZERO) // true
new BigDecimal("0.00").equals(BigDecimal.ZERO) // false!

portanto, não é adequado para uma comparação puramente numérica. No entanto, BigDecimal.compareTo()não considera escala ao comparar:

new BigDecimal("0").compareTo(BigDecimal.ZERO) == 0 // true
new BigDecimal("0.00").compareTo(BigDecimal.ZERO) == 0 // true
Boêmio
fonte
BigDecimal.ZERO.compareTo (price) == 0
Jackkobec 27/01
97

Como alternativa, signum () pode ser usado:

if (price.signum() == 0) {
    return true;
}
kman
fonte
21
Talvez seja mais rápido, mas compareTo (BigDecimal.ZERO) é mais legível.
ElYeante
@ElYeante, você sempre pode embrulhar isso com método, que tem o nome mais legível, ou mesmo descreve parte do seu negócio-lógica, connectaed com tal comparação
Wega
3
Signum Unfortuntely () não é nulo-safe, enquanto compareTo é, quando se compara como BigDecimal.ZERO.compareTo (), para prestar atenção ao que
Wega
15
@WeGa Isso não é verdade: BigDecimal.ZERO.compareTo(null)lançará NPE
ACV
5
@ ACV, obrigado pela sua vigilância. Observado o código fonte, compareTo () espera apenas um argumento não nulo.
Wega
24

Há uma constante que você pode verificar:

someBigDecimal.compareTo(BigDecimal.ZERO) == 0
pablochan
fonte
3
Permissão para roubar sua terminologia de uma "condição Yoda" solicitada.
SimplyPanda
3
Isso é fantástico .
SimplyPanda
O comportamento do Java BigDecimal equalse compareTonão é o que você pensa. docs.oracle.com/javase/1.5.0/docs/api/java/math/…
nhahtdh
2
O compareTo do BigDecimal ainda lançará uma exceção se você passar um nulo.
John Jiang
5

Eu costumo usar o seguinte:

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

Como alternativa, acho que vale a pena mencionar que o comportamento dos métodos igual e compareTo na classe BigDecimal não são consistentes entre si .

Isso basicamente 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

Portanto, você deve ter muito cuidado com a escala em sua someValuevariável, caso contrário, obterá um resultado inesperado.

Edwin Dalorzo
fonte
5

Você deseja usar equals (), pois eles são objetos, e utilizar a instância ZERO integrada:

if(selectPrice.equals(BigDecimal.ZERO))

Observe que .equals()leva em consideração a escala, portanto, a menos que selectPrice seja a mesma escala (0) .ZERO, isso retornará false.

Para tirar a escala da equação, por assim dizer:

if(selectPrice.compareTo(BigDecimal.ZERO) == 0)

Devo observar que, para certas situações matemáticas 0.00 != 0, é por isso que imagino .equals()leva em conta a escala. 0.00dá precisão ao centésimo lugar, enquanto 0que não é tão preciso. Dependendo da situação que você pode querer manter .equals().

NominSim
fonte
O comportamento do Java BigDecimal equalse compareTonão é o que você pensa. docs.oracle.com/javase/1.5.0/docs/api/java/math/…
nhahtdh
Importa-se de explicar o que você quer dizer em vez de vincular aos documentos? O que sugeri deve funcionar para o OP.
NominSim
A resposta de Edwin Dalorzo explica muito bem, na verdade. equalsleva em conta a escala, que não é o que queremos aqui.
Nhahtdh 31/08/12
@nhahtdh Obrigado pela informação, de fato, embora existam situações em que equals deve ser usado em vez de compareTo(). O OP não especifica que tipo de matemática ele está usando, então você está certo, é melhor dar a ele as duas opções.
NomSim
3

GriffeyDog está definitivamente correto:

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

Embora eu compreenda as vantagens da comparação BigDecimal, não consideraria uma construção intuitiva (como os operadores ==, <,>, <=,> = são). Quando você está segurando um milhão de coisas (ok, sete coisas) em sua cabeça, qualquer coisa que possa reduzir sua carga cognitiva é uma coisa boa. Então, eu criei algumas funções úteis de conveniência:

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);
}

Aqui está como usá-los:

    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));

Os resultados são assim:

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
fonte
1
Existem várias respostas explicando exatamente isso. Qual o sentido de adicionar outra resposta? Se você tiver informações adicionais, é uma boa ideia adicionar uma nova resposta, mas esse não é o caso nesta postagem.
Tom
Ponto tomado. No entanto, quando estou aprendendo alguma coisa, gosto de ver o maior número possível de exemplos, mesmo que sejam semelhantes. Para você, Tom, adicionei minha biblioteca que achei útil. Sua milhagem pode variar. :-)
Tihamer
0

Só quero compartilhar aqui algumas extensões úteis para o kotlin

fun BigDecimal.isZero() = compareTo(BigDecimal.ZERO) == 0
fun BigDecimal.isOne() = compareTo(BigDecimal.ONE) == 0
fun BigDecimal.isTen() = compareTo(BigDecimal.TEN) == 0
Nokuap
fonte
-2
BigDecimal.ZERO.setScale(2).equals(new BigDecimal("0.00"));
DongHoon Kim
fonte
1
Embora esse código possa responder à pergunta, fornecer um contexto adicional sobre como e / ou por que resolve o problema melhoraria o valor a longo prazo da resposta. Lembre-se de que você está respondendo à pergunta dos leitores no futuro, não apenas à pessoa que está perguntando agora! Por favor edite sua resposta para adicionar uma explicação, e dar uma indicação do que limitações e premissas se aplicam. Também não custa mencionar por que essa resposta é mais apropriada do que outras.
Dev-IL
-8

Há uma constante estática que representa 0 :

BigDecimal.ZERO.equals(selectPrice)

Você deve fazer isso em vez de:

selectPrice.equals(BigDecimal.ZERO)

para evitar o caso onde selectPriceestá null.

tskuzzy
fonte
3
O comportamento do Java BigDecimal equalse compareTonão é o que você pensa. docs.oracle.com/javase/1.5.0/docs/api/java/math/…
nhahtdh
assim, para a segunda linha ... se selectedPrice for nulo, ele lançará NullPointerException.
user3206236