Java BigDecimal değişken == 0 olup olmadığını nasıl kontrol edebilirim?


203

Java aşağıdaki kodu var;

BigDecimal price; // assigned elsewhere

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

İf koşulunu yazmanın en iyi yolu nedir?


12
Birçok yanıt BigDecimal'in .equals () yöntemini kullanmanızı önerir. Ancak bu yöntem ölçeği dikkate alır, bu yüzden CompareTo () kullanmaya eşdeğer değildir.
GriffeyDog

Yanıtlar:


475

Şunun compareTo(BigDecimal.ZERO)yerine kullanın equals():

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

BigDecimalSabit ile karşılaştırmak her yürütmeyi BigDecimal.ZEROinşa etmek zorunda new BigDecimal(0)kalmaz.

FYI, BigDecimalaynı zamanda sabitler BigDecimal.ONEve BigDecimal.TENsize kolaylık sağlamak için.


Not!

Kullanamamanızın nedeni BigDecimal#equals(), ölçeği dikkate almasıdır :

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

bu yüzden tamamen sayısal bir karşılaştırma için uygun değildir. Ancak, BigDecimal.compareTo()karşılaştırırken ölçeği dikkate almaz:

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

1
BigDecimal.ZERO.compareTo (fiyat) == 0
Jackkobec

97

Alternatif olarak, signum () kullanılabilir:

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

21
Belki daha hızlıdır, ama CompareTo (BigDecimal.ZERO) daha okunabilir.
ElYeante

@ElYeante, bunu her zaman daha okunabilir bir ada sahip bir yöntemle sarabilir veya hatta bu tür bir karşılaştırmayla bağlantılı iş mantığınızın bir kısmını açıklayabilirsiniz
WeGa

3
Maalesef signum () null-güvenli değil, karşılaştırmak ise BigDecimal.ZERO.compareTo () gibi karşılaştırırken, buna dikkat edin
WeGa

15
@WeGa Bu doğru değil: NPE'yi BigDecimal.ZERO.compareTo(null)atacak
ACV

5
@ACV, uyanıklığınız için teşekkürler. Kaynak koduna bakıldığında, CompareTo () yalnızca null olmayan argüman bekler.
WeGa


5

Genellikle aşağıdakileri kullanırım:

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

5

Alternatif olarak, BigDecimal sınıfındaki eşittir ve CompareTo yöntemlerinin davranışlarının birbiriyle tutarlı olmadığını belirtmeye değer .

Bu temel olarak şu anlama gelir:

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

Bu nedenle, someValuedeğişkeninizdeki ölçeğe çok dikkat etmelisiniz , aksi takdirde beklenmedik sonuç alırsınız.


5

Nesneler oldukları için equals () öğesini kullanmak ve yerleşik ZERO örneğini kullanmak istersiniz:

if(selectPrice.equals(BigDecimal.ZERO))

.equals()Ölçeğin dikkate alındığına dikkat edin , bu nedenle selectPrice aynı ölçek (0) olmadığı sürece .ZERObu yanlış döndürür.

Ölçeği denklemden olduğu gibi çıkarmak:

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

Bazı matematiksel durumlar için 0.00 != 0, bu yüzden .equals()ölçeği dikkate aldığını hayal etmeliyim . 0.00yüzüncü yere hassasiyet verirken 0, o kadar da hassas değil. Duruma bağlı kalmak isteyebilirsiniz .equals().


Java BigDecimal'in davranışı equalsve compareTodüşündüğünüz gibi değil. docs.oracle.com/javase/1.5.0/docs/api/java/math/…
nhahtdh

Dokümanlara bağlamak yerine ne demek istediğinizi açıklamak ister misiniz? Önerdiğim OP için çalışmalı.
NominSim

Edwin Dalorzo'nun cevabı aslında oldukça iyi açıklıyor. equalsölçeği hesaba katar, bu da burada istediğimiz şey değildir.
nhahtdh

@nhahtdh Bilgi için teşekkürler, aslında bunun yerine kullanılması equals gereken durumlar vardır compareTo(). OP ne tür bir matematik kullandığını belirtmiyor, bu yüzden ona her iki seçeneği de vermek daha doğru.
NominSim

3

GriffeyDog kesinlikle doğrudur:

Kod:

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

Sonuçlar:

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

Ben BigDecimal karşılaştırmanın avantajlarını anlasam da, sezgisel bir yapı olarak düşünmüyorum (==, <,>, <=,> = operatörleri gibi). Kafanızda bir milyon şey (tamam, yedi şey) tutarken, bilişsel yükünüzü azaltabileceğiniz her şey iyi bir şeydir. Bu yüzden bazı kullanışlı kolaylık fonksiyonları oluşturdum:

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

Bunları nasıl kullanacağınız aşağıda açıklanmıştır:

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

Sonuçlar şöyle görünür:

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
Bunu tam olarak açıklayan birden fazla cevap var. Başka bir cevap eklemenin anlamı nedir? Ek bilgileriniz varsa, yeni yanıt eklemek iyi bir fikirdir, ancak bu yazıdaki durum böyle değildir.
Tom

Alınan nokta. Ancak, bir şey öğrenirken, benzer olsalar bile, mümkün olduğunca çok örnek görmek isterim. Senin için Tom, yararlı bulduğum kütüphanemi ekledim. Milajınız değişebilir. :-)
Tihamer

0

Burada kotlin için bazı yararlı uzantıları paylaşmak istiyorum

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
Bu kod soruyu cevaplayabilirken, sorunun nasıl ve / veya neden çözüldüğüne ilişkin ek bağlam sağlamak yanıtlayıcının uzun vadeli değerini artıracaktır. Sadece şu anda soran kişi için değil, gelecekte okuyucular için soruyu cevapladığınızı unutmayın! Lütfen açıklama eklemek için cevabınızı düzenleyin ve hangi sınırlamaların ve varsayımların geçerli olduğunu belirtin. Bu cevabın neden diğerlerinden daha uygun olduğunu belirtmek de zarar vermez.
Dev-iL

-8

0'ı temsil eden statik bir sabit vardır :

BigDecimal.ZERO.equals(selectPrice)

Bunu aşağıdakiler yerine yapmalısınız:

selectPrice.equals(BigDecimal.ZERO)

durumdan kaçınmak için nerede selectPriceolduğunu null.


3
Java BigDecimal'in davranışı equalsve compareTodüşündüğünüz gibi değil. docs.oracle.com/javase/1.5.0/docs/api/java/math/…
nhahtdh

yani ikinci satır için ... seçilirse Price null olursa NullPointerException özel durumunu atar.
user3206236
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.