Come verificare se la variabile BigDecimal == 0 in Java?


202

Ho il seguente codice in Java;

BigDecimal price; // assigned elsewhere

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

Qual è il modo migliore per scrivere la condizione if?


12
Molte risposte suggeriscono di usare il metodo .equals () di BigDecimal. Ma quel metodo prende in considerazione la scala, quindi non equivale all'utilizzo di compareTo ().
GriffeyDog,

Risposte:


474

Usa compareTo(BigDecimal.ZERO)invece di equals():

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

Il confronto con la BigDecimalcostante BigDecimal.ZEROevita di dover costruire new BigDecimal(0)ogni esecuzione.

Cordiali saluti, BigDecimalha anche costanti BigDecimal.ONEe BigDecimal.TENper vostra comodità.


Nota!

Il motivo per cui non BigDecimal#equals()è possibile utilizzare è che prende in considerazione la scala :

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

quindi non è adatto per un confronto puramente numerico. Tuttavia, BigDecimal.compareTo()non considera la scala quando si confronta:

new BigDecimal("0").compareTo(BigDecimal.ZERO) == 0 // true
new BigDecimal("0.00").compareTo(BigDecimal.ZERO) == 0 // true

BigDecimal.ZERO.compareTo (prezzo) == 0
Jackkobec,

97

In alternativa, è possibile utilizzare signum () :

if (price.signum() == 0) {
    return true;
}

21
Forse è più veloce, ma compareTo (BigDecimal.ZERO) è più leggibile.
ElYeante

@ElYeante, puoi sempre includerlo con il metodo, che ha un nome più leggibile, o addirittura descrive parte della tua logica aziendale,
connessa

3
Sfortunatamente signum () non è null-safe, mentre compareTo, quando si confronta come BigDecimal.ZERO.compareTo (), quindi presta attenzione a questo
WeGa,

15
@WeGa Non è vero: BigDecimal.ZERO.compareTo(null)lanci NPE
ACV

5
@ACV, grazie per la tua vigilanza. Osservato il codice sorgente, compareTo () si aspetta davvero solo argomenti non nulli.
WeGa,

24

C'è una costante che puoi verificare contro:

someBigDecimal.compareTo(BigDecimal.ZERO) == 0

3
È richiesta l'autorizzazione a rubare la terminologia di una "condizione Yoda".
SimplyPanda,


Il comportamento di Java BigDecimal equalse compareTonon è come pensi. docs.oracle.com/javase/1.5.0/docs/api/java/math/…
nhahtdh

2
Il confronto di BigDecimalTo genererà comunque un'eccezione se si passa a un valore null.
John Jiang,

5

Di solito uso quanto segue:

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

5

In alternativa, penso che valga la pena ricordare che il comportamento di uguali e di confronto con i metodi della classe BigDecimal non sono coerenti tra loro .

Ciò significa sostanzialmente che:

BigDecimal someValue = new BigDecimal("0.00");
System.out.println(someValue.compareTo(BigDecimal.ZERO)==0); //true
System.out.println(someValue.equals(BigDecimal.ZERO)); //false

Pertanto, devi stare molto attento con la scala nella tua someValuevariabile, altrimenti otterrai risultati inaspettati.


5

Si desidera utilizzare equals () poiché sono oggetti e utilizzare l'istanza ZERO integrata:

if(selectPrice.equals(BigDecimal.ZERO))

Nota che .equals()tiene conto della scala, quindi a meno che selectPrice sia la stessa scala (0) di .ZEROallora questo restituirà false.

Per togliere la scala dall'equazione per così dire:

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

Dovrei notare che per alcune situazioni matematiche, 0.00 != 0motivo per cui immagino che .equals()tenga conto della scala. 0.00dà precisione al centesimo posto, mentre 0non è così preciso. A seconda della situazione che potresti voler rispettare .equals().


Il comportamento di Java BigDecimal equalse compareTonon è come pensi. docs.oracle.com/javase/1.5.0/docs/api/java/math/…
nhahtdh

Ti interessa spiegare cosa intendi invece di collegarti ai documenti? Quello che ho suggerito dovrebbe funzionare per il PO.
NominSim

La risposta di Edwin Dalorzo lo spiega abbastanza bene, in realtà. equalstiene conto della scala, che non è ciò che vogliamo qui.
nhahtdh,

@nhahtdh Grazie per le informazioni, in realtà ci sono situazioni in cui equals dovrebbero essere utilizzate al posto di compareTo(). L'OP non specifica quale tipo di matematica sta usando, quindi hai ragione è meglio dargli entrambe le opzioni.
NominSim

3

GriffeyDog è decisamente corretto:

Codice:

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

risultati:

myBigDecimal=0.000000
BigDecimal.valueOf(0.000000)=0.0
 equals=false
compare=true

Mentre comprendo i vantaggi del confronto BigDecimal, non lo considero un costrutto intuitivo (come gli operatori ==, <,>, <=,> =). Quando hai in testa un milione di cose (ok, sette cose) nella tua testa, allora tutto ciò che puoi ridurre il tuo carico cognitivo è una buona cosa. Quindi ho creato alcune utili funzioni utili:

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

Ecco come usarli:

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

I risultati si presentano così:

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

1
Ci sono più risposte che spiegano esattamente questo. Qual è il punto di aggiungere un'altra risposta? Se hai ulteriori informazioni, allora è una buona idea aggiungere una nuova risposta, ma questo non è il caso in questo post.
Tom,

Punto preso. Tuttavia, quando sto imparando qualcosa, mi piace vedere quanti più esempi possibili, anche se sono simili. Per te, Tom, ho aggiunto la mia biblioteca che ho trovato utile. Il tuo chilometraggio può variare. :-)
Tihamer

0

Voglio solo condividere qui alcune utili estensioni per kotlin

fun BigDecimal.isZero() = compareTo(BigDecimal.ZERO) == 0
fun BigDecimal.isOne() = compareTo(BigDecimal.ONE) == 0
fun BigDecimal.isTen() = compareTo(BigDecimal.TEN) == 0

-2
BigDecimal.ZERO.setScale(2).equals(new BigDecimal("0.00"));

1
Mentre questo codice può rispondere alla domanda, fornire un contesto aggiuntivo riguardo a come e / o perché risolve il problema migliorerebbe il valore a lungo termine della risposta. Ricorda che stai rispondendo alla domanda per i lettori in futuro, non solo per la persona che chiede ora! Si prega di modificare la risposta di aggiungere una spiegazione, e dare un'indicazione di ciò si applicano le limitazioni e le assunzioni. Inoltre non fa male menzionare perché questa risposta è più appropriata di altre.
Dev-iL

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.