Làm cách nào để kiểm tra xem biến BigDecimal == 0 trong java không?


202

Tôi có đoạn mã sau trong Java;

BigDecimal price; // assigned elsewhere

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

Cách tốt nhất để viết điều kiện if là gì?


12
Nhiều câu trả lời đang đề xuất sử dụng phương thức .equals () của BigDecimal. Nhưng phương pháp đó có quy mô được xem xét, do đó không tương đương với việc sử dụng so sánh ().
GriffeyDog

Câu trả lời:


472

Sử dụng compareTo(BigDecimal.ZERO)thay vì equals():

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

So sánh với BigDecimalhằng số BigDecimal.ZEROtránh phải xây dựng một new BigDecimal(0)thực thi.

FYI, BigDecimalcũng có hằng số BigDecimal.ONEBigDecimal.TENđể thuận tiện cho bạn.


Ghi chú!

Lý do bạn không thể sử dụng BigDecimal#equals()là nó có quy mô xem xét:

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

vì vậy nó không phù hợp để so sánh hoàn toàn bằng số. Tuy nhiên, BigDecimal.compareTo()không xem xét quy mô khi so sánh:

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

BigDecimal.ZERO.compareTo (giá) == 0
Jackkobec

97

Ngoài ra, Signum () có thể được sử dụng:

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

21
Có thể nó nhanh hơn, nhưng so sánh (BigDecimal.ZERO) dễ đọc hơn.
ElYeante

@ElYeante, bạn luôn có thể kết hợp điều này với phương thức, có tên dễ đọc hơn hoặc thậm chí mô tả một phần logic kinh doanh của bạn, được kết nối với so sánh như vậy
WeGa

3
Đáng tiếc là Signum () không an toàn, trong khi so sánh là, khi so sánh như BigDecimal.ZERO.compareTo (), vì vậy hãy chú ý đến điều đó
WeGa

15
@ WEGa Điều đó không đúng: BigDecimal.ZERO.compareTo(null)sẽ ném NPE
ACV

5
@ACV, cảm ơn sự cảnh giác của bạn. Nhìn vào mã nguồn, so sánh () chỉ mong đợi đối số không null thực sự.
WeGa

24

Có một hằng số mà bạn có thể kiểm tra lại:

someBigDecimal.compareTo(BigDecimal.ZERO) == 0

3
Quyền đánh cắp thuật ngữ của bạn về "điều kiện Yoda" được yêu cầu.
SimplyPanda


Hành vi của Java BigDecimal equalscompareTokhông như bạn nghĩ. docs.oracle.com/javase/1.5.0/docs/api/java/math/ory
nhahtdh

2
So sánh của BigDecimal vẫn sẽ đưa ra một ngoại lệ nếu bạn chuyển thành null.
John Jiang

5

Tôi thường sử dụng như sau:

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

5

Ngoài ra, tôi nghĩ điều đáng nói là hành vi của các phương thức bằng và so sánh trong lớp BigDecimal không nhất quán với nhau .

Điều này về cơ bản có nghĩa là:

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

Do đó, bạn phải rất cẩn thận với thang đo trong someValuebiến của mình , nếu không bạn sẽ nhận được kết quả bất ngờ.


5

Bạn sẽ muốn sử dụng bằng () vì chúng là các đối tượng và sử dụng thể hiện ZERO tích hợp:

if(selectPrice.equals(BigDecimal.ZERO))

Lưu ý rằng .equals()sẽ tính tỷ lệ, vì vậy trừ khi selectprice có cùng tỷ lệ (0) .ZEROthì điều này sẽ trả về false.

Để lấy quy mô ra khỏi phương trình như sau:

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

Tôi nên lưu ý rằng đối với các tình huống toán học nhất định 0.00 != 0, đó là lý do tại sao tôi tưởng tượng .equals()sẽ tính đến quy mô. 0.00đưa ra độ chính xác cho vị trí thứ một trăm, trong khi đó 0không chính xác. Tùy thuộc vào tình huống mà bạn có thể muốn gắn bó .equals().


Hành vi của Java BigDecimal equalscompareTokhông như bạn nghĩ. docs.oracle.com/javase/1.5.0/docs/api/java/math/ory
nhahtdh

Quan tâm để giải thích những gì bạn có ý nghĩa thay vì liên kết đến các tài liệu? Những gì tôi đề nghị nên làm việc cho OP.
NominSim

Câu trả lời của Edwin Dalorzo giải thích nó khá tốt, thực sự. equalscó quy mô vào tài khoản, đó không phải là những gì chúng ta muốn ở đây.
nhahtdh

@nhahtdh Cảm ơn thông tin, trên thực tế, mặc dù có những tình huống equals nên được sử dụng thay vì compareTo(). OP không chỉ định loại toán học mà anh ta đang sử dụng, vì vậy bạn nói đúng hơn là cung cấp cho anh ta cả hai tùy chọn.
NominSim

3

GriffeyDog hoàn toàn chính xác:

Mã số:

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

Các kết quả:

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

Mặc dù tôi hiểu các ưu điểm của so sánh BigDecimal, tôi sẽ không coi đó là một cấu trúc trực quan (như các toán tử ==, <,>, <=,> =). Khi bạn đang giữ một triệu thứ (ok, bảy thứ) trong đầu, thì bất cứ điều gì bạn có thể giảm tải nhận thức là một điều tốt. Vì vậy, tôi đã xây dựng một số chức năng tiện lợi hữu ích:

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

Đây là cách sử dụng chúng:

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

Các kết quả trông như thế này:

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
Có nhiều câu trả lời giải thích chính xác điều đó. Điểm của một câu trả lời khác là gì? Nếu bạn có thêm thông tin, thì nên thêm câu trả lời mới, nhưng đây không phải là trường hợp trong bài viết này.
Tom

Điểm lấy. Tuy nhiên, khi tôi đang học một cái gì đó, tôi muốn xem càng nhiều ví dụ càng tốt, ngay cả khi chúng giống nhau. Đối với bạn, Tom, tôi đã thêm thư viện của mình mà tôi thấy hữu ích. Milage của bạn có thể thay đổi. :-)
Tihamer

0

Chỉ muốn chia sẻ ở đây một số tiện ích mở rộng hữu ích cho 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
Mặc dù mã này có thể trả lời câu hỏi, việc cung cấp ngữ cảnh bổ sung về cách thức và / hoặc lý do giải quyết vấn đề sẽ cải thiện giá trị lâu dài của câu trả lời. Hãy nhớ rằng bạn đang trả lời câu hỏi cho độc giả trong tương lai, không chỉ là người hỏi bây giờ! Vui lòng chỉnh sửa câu trả lời của bạn để thêm lời giải thích và đưa ra dấu hiệu về những hạn chế và giả định được áp dụng. Cũng không hại khi đề cập đến lý do tại sao câu trả lời này phù hợp hơn những câu hỏi khác.
Dev-iL

-8

Có một hằng số tĩnh đại diện cho 0 :

BigDecimal.ZERO.equals(selectPrice)

Bạn nên làm điều này thay vì:

selectPrice.equals(BigDecimal.ZERO)

để tránh trường hợp selectPricenull.


3
Hành vi của Java BigDecimal equalscompareTokhông như bạn nghĩ. docs.oracle.com/javase/1.5.0/docs/api/java/math/ory
nhahtdh

vì vậy đối với dòng thứ hai ... nếu được chọn Giá trị là null thì nó sẽ chỉ ném NullPulumException.
dùng3206236
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.