วิธีการตรวจสอบว่าตัวแปร BigDecimal == 0 ใน java?


202

ฉันมีรหัสต่อไปนี้ใน Java;

BigDecimal price; // assigned elsewhere

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

วิธีที่ดีที่สุดในการเขียนเงื่อนไข if คืออะไร?


12
มีคำตอบมากมายที่แนะนำให้ใช้วิธีการ. Equals () ของ BigDecimal แต่วิธีการดังกล่าวคำนึงถึงการปรับขนาดจึงไม่เทียบเท่ากับการใช้ comparTo ()
GriffeyDog

คำตอบ:


472

ใช้compareTo(BigDecimal.ZERO)แทนequals():

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

เปรียบเทียบกับBigDecimalค่าคงที่BigDecimal.ZEROเพื่อหลีกเลี่ยงการสร้างnew BigDecimal(0)ทุกการกระทำ

FYI BigDecimalยังมีค่าคงที่BigDecimal.ONEและBigDecimal.TENเพื่อความสะดวกของคุณ


บันทึก!

เหตุผลที่คุณไม่สามารถใช้BigDecimal#equals()ก็คือว่ามันจะใช้เวลาขนาดเข้าสู่การพิจารณา:

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

ดังนั้นจึงไม่เหมาะสำหรับการเปรียบเทียบตัวเลขอย่างหมดจด อย่างไรก็ตามBigDecimal.compareTo()ไม่ควรพิจารณาขนาดเมื่อเปรียบเทียบ:

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

BigDecimal.ZERO.compareTo (ราคา) == 0
Jackkobec

97

อีกทางเลือกหนึ่งsignum ()สามารถใช้:

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

21
อาจจะเร็วกว่า แต่ CompareTo (BigDecimal.ZERO) สามารถอ่านได้มากขึ้น
ElYeante

@ElYeante คุณสามารถห่อสิ่งนี้ด้วยวิธีการที่มีชื่อที่อ่านได้มากกว่าหรืออธิบายส่วนหนึ่งของตรรกะทางธุรกิจของคุณเชื่อมต่อกับการเปรียบเทียบดังกล่าว
WeGa

3
Signal Unfortuntely () ไม่ปลอดภัยในขณะที่ comparTo คือเมื่อเปรียบเทียบเช่น BigDecimal.ZERO.compareTo () ดังนั้นโปรดใส่ใจกับสิ่งนั้น
WeGa

15
@WeGa ไม่เป็นความจริง: BigDecimal.ZERO.compareTo(null)จะโยน NPE
ACV

5
@ ACV ขอบคุณสำหรับความระมัดระวังของคุณ ดูที่ซอร์สโค้ด comparTo () คาดว่าจะมีอาร์กิวเมนต์ที่ไม่ใช่นัล
WeGa

24

มีค่าคงที่ที่คุณสามารถตรวจสอบกับ:

someBigDecimal.compareTo(BigDecimal.ZERO) == 0

3
ได้รับอนุญาตให้ขโมยคำศัพท์ของคุณของ "เงื่อนไขโยดา" ที่ร้องขอ
SimplyPanda


พฤติกรรมของ Java BigDecimal equalsและcompareToไม่ได้เป็นอย่างที่คุณคิด docs.oracle.com/javase/1.5.0/docs/api/java/math/…
nhahtdh

2
BigDecimal's comparTo จะยังคงมีข้อยกเว้นถ้าคุณผ่านเป็นโมฆะ
John Jiang


5

หรือฉันคิดว่ามันเป็นมูลค่าการกล่าวขวัญว่าพฤติกรรมของเท่ากับและวิธี compareTo ในชั้นเรียน BigDecimal ที่ไม่สอดคล้องกับแต่ละอื่น ๆ

โดยทั่วไปหมายความว่า:

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

ดังนั้นคุณต้องระมัดระวังอย่างมากกับสเกลในsomeValueตัวแปรของคุณมิฉะนั้นคุณจะได้ผลลัพธ์ที่ไม่คาดคิด


5

คุณต้องการใช้เท่ากับ () เนื่องจากมันเป็นวัตถุและใช้ประโยชน์จากอินสแตนซ์ของศูนย์:

if(selectPrice.equals(BigDecimal.ZERO))

โปรดทราบว่า.equals()คำนึงถึงสเกลด้วยตนเองดังนั้นหาก selectPrice เป็นสเกลเดียวกัน (0) .ZEROดังนั้นจะส่งคืนค่าเท็จ

ที่จะไต่ออกจากสมการที่เป็น:

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

ฉันควรทราบว่าสำหรับสถานการณ์ทางคณิตศาสตร์บางอย่าง0.00 != 0ซึ่งเป็นเหตุผลที่ฉันจินตนาการถึง.equals()การพิจารณาขนาด 0.00ให้ความแม่นยำกับตำแหน่งที่ร้อยในขณะที่0ไม่แม่นยำ .equals()ขึ้นอยู่กับสถานการณ์ที่คุณอาจต้องการที่จะติดกับ


พฤติกรรมของ Java BigDecimal equalsและcompareToไม่ได้เป็นอย่างที่คุณคิด docs.oracle.com/javase/1.5.0/docs/api/java/math/…
nhahtdh

สนใจที่จะอธิบายสิ่งที่คุณหมายถึงแทนที่จะเชื่อมโยงกับเอกสารหรือไม่ สิ่งที่ฉันแนะนำควรใช้กับ OP
NominSim

คำตอบของ Edwin Dalorzo อธิบายได้ค่อนข้างดีจริงๆ equalsพิจารณาขนาดซึ่งไม่ใช่สิ่งที่เราต้องการที่นี่
nhahtdh

ขอบคุณ @nhahtdh สำหรับข้อมูลที่ในความเป็นจริงแม้ว่าจะมีสถานการณ์ที่equals ควรจะcompareTo()นำมาใช้แทน OP ไม่ได้ระบุประเภทของคณิตศาสตร์ที่เขาใช้ดังนั้นคุณพูดถูกต้องดีกว่าที่จะให้ตัวเลือกแก่เขาทั้งคู่
NominSim

3

GriffeyDog ถูกต้องแน่นอน:

รหัส:

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

ผล:

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

ในขณะที่ฉันเข้าใจถึงข้อดีของการเปรียบเทียบ BigDecimal ฉันจะไม่พิจารณาว่าเป็นโครงสร้างที่ใช้งานง่าย (เช่น ==, <,>, <=,> = โอเปอเรเตอร์) เมื่อคุณถือล้านสิ่ง (ตกลง, เจ็ดสิ่ง) อยู่ในหัวของคุณแล้วอะไรก็ตามที่คุณสามารถลดภาระการรับรู้ของคุณเป็นสิ่งที่ดี ดังนั้นฉันจึงสร้างฟังก์ชั่นอำนวยความสะดวกที่มีประโยชน์:

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

นี่คือวิธีการใช้งาน:

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

ผลลัพธ์มีลักษณะดังนี้:

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
มีหลายคำตอบที่อธิบายได้อย่างแม่นยำ ประเด็นของการเพิ่มคำตอบอื่นคืออะไร? หากคุณมีข้อมูลเพิ่มเติมเป็นความคิดที่ดีที่จะเพิ่มคำตอบใหม่ แต่นี่ไม่ใช่กรณีในโพสต์นี้
Tom

จุดที่ถ่าย อย่างไรก็ตามเมื่อฉันเรียนรู้บางอย่างฉันชอบที่จะเห็นตัวอย่างให้มากที่สุดเท่าที่จะเป็นไปได้แม้ว่าจะคล้ายกันก็ตาม ทอมคุณเพิ่มห้องสมุดที่ฉันคิดว่ามีประโยชน์สำหรับคุณแล้ว ระยะของคุณอาจแตกต่างกันไป :-)
Tihamer

0

เพียงต้องการแบ่งปันส่วนขยายที่เป็นประโยชน์สำหรับ 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
ในขณะที่รหัสนี้อาจตอบคำถามให้บริบทเพิ่มเติมเกี่ยวกับวิธีการและ / หรือทำไมมันแก้ปัญหาจะปรับปรุงค่าระยะยาวของคำตอบ โปรดจำไว้ว่าคุณกำลังตอบคำถามสำหรับผู้อ่านในอนาคตไม่ใช่เพียงแค่คนที่ถามตอนนี้! โปรดแก้ไขคำตอบของคุณเพื่อเพิ่มคำอธิบายและระบุข้อ จำกัด และสมมติฐานที่ใช้ ไม่ต้องพูดถึงว่าทำไมคำตอบนี้จึงเหมาะสมกว่าคำตอบ
Dev-iL

-8

มีค่าคงที่คงที่ที่แสดงถึง 0 :

BigDecimal.ZERO.equals(selectPrice)

คุณควรทำสิ่งนี้แทน:

selectPrice.equals(BigDecimal.ZERO)

เพื่อหลีกเลี่ยงกรณีที่เป็นselectPricenull


3
พฤติกรรมของ Java BigDecimal equalsและcompareToไม่ได้เป็นอย่างที่คุณคิด docs.oracle.com/javase/1.5.0/docs/api/java/math/…
nhahtdh

ดังนั้นสำหรับบรรทัดที่สอง ... ถ้าเลือกราคาเป็นโมฆะมันก็จะโยน NullPointerException
user3206236
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.