2011-07-22 106 views
112

考慮簡單的測試類:BigDecimal的equals()方法對的compareTo()

import java.math.BigDecimal; 

/** 
* @author The Elite Gentleman 
* 
*/ 
public class Main { 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     // TODO Auto-generated method stub 
     BigDecimal x = new BigDecimal("1"); 
     BigDecimal y = new BigDecimal("1.00"); 
     System.out.println(x.equals(y)); 
     System.out.println(x.compareTo(y) == 0 ? "true": "false"); 
    } 

} 

可以(有意識)說x等於y(不是對象引用),但是當你運行該程序時,以下結果表明:

false 
true 

問題:什麼是在BigDecimalcompareTo()equals()之間的區別在於compareTo可以確定x是EQUA升至y

PS:我看到BigDecimal在equals()方法上有一個inflate()方法。 inflate()實際上做了什麼?

+0

廣告'膨脹()':它不是公共API的一部分,因爲它僅操縱內部表示有「外」沒有明顯的效果。所以除非你真的想深入研究'BigDecimal'的實現,否則我建議你忽略這個方法。 –

+0

可以在這裏找到一個簡短的說明和源代碼片段[here](http://stackoverflow.com/a/39163942/4723795) – xenteros

回答

157

答案是在the JavaDoc of the equals() method

不同於compareTo,這種方法考慮兩個BigDecimal對象等於僅當它們在值和尺度相等(當用這種方法比較由此2.0不等於2.00)。

換句話說:equals()檢查是否BigDecimal對象方面完全相同相同在compareTo()「僅」比較它們的數值。

+13

如果您沒有仔細閱讀JavaDoc,那麼這是'BigDecimal'中非常棘手的部分。 :) - 我們從中得到了一些奇怪的錯誤,直到我們意識到差異。 – Thomas

+3

標準API的許多部分碰巧「不直觀」,當直覺的東西不正確時。 BigDecimal就是這樣的一個例子。因此,應該總是檢查JavaDoc。 *至少*一旦你發現一些奇怪的事情正在發生。 –

+6

有趣。在閱讀你的答案後,我只檢查了Comparable,它聲明與equals相等「強烈建議(但不要求)」 – SJuan76

1

我看到BigDecimal在equals()方法上有一個inflate()方法。 inflate()實際上做了什麼?

基本上,inflate()呼叫BigInteger.valueOf(intCompact)如果必要的話,即,它創建存儲作爲從long intCompact一個BigInteger非標度值。如果您不需要BigInteger並且非縮放值適合longBigDecimal似乎儘可能地節省空間。

+0

我不知道你寫了什麼(特別是最後一句話)。 –

+0

@The Elite Gentlement最後一句應該說內部'BigDecimal'在「long」和「BigInteger」中保留其未縮放值。如果內部不需要'BigInteger',它不會被創建,但是如果需要的話(例如當'equals'遇到膨脹和非膨脹的'BigDecimal時'),則使用'inflate()'來創建它。 - 總結一下:'inflate()'在必要時處理內部轉換,並且由於它是私有的,所以對於類的用戶應該沒有關係。 – Thomas

-3

您還可以使用雙值進行比較

BigDecimal a= new BigDecimal("1.1"); BigDecimal b =new BigDecimal("1.1"); 
System.out.println(a.doubleValue()==b.doubleValue()); 
+3

一旦數字足夠大,這將不起作用。 – xenteros

+2

請儘可能避免使用此解決方案。即使是雙打也應該與「epsilon」進行比較。 BigDecimal並沒有意義,並且將它比作雙打,你很可能會拍攝自己的腿。 –