在 Java 中將 Long 轉換為 BigDecimal
1. 概述
在本教程中,我們將探索兩種在 Java 中將Long
轉換為BigDecimal
的有效方法。
2.問題介紹
當我們談論將Long
轉換為BigDecimal
時,有些人可能會認為兩者都是Number
類型,因此我們可以將Long
轉換為BigDecimal
,如BigDecimal bd = (BigDecimal) longValue.
但是,這不能編譯:
java: incompatible types: java.lang.Long cannot be converted to java.math.BigDecimal
接下來,讓我們探討幾種將Long
轉換為BigDecimal.
為簡單起見,我們將使用單元測試斷言來驗證每種方法是否按預期工作。
3. 使用BigDecimal
構造函數
BigDecimal
類提供了一個構造函數來接受long
值並創建BigDecimal
實例。接下來,讓我們創建一個測試來檢查這種方法是否滿足我們的需求:
Long num4 = 4L;
BigDecimal result4 = new BigDecimal(num4);
assertEquals(new BigDecimal("4"), result4);
Long num42 = -42L;
BigDecimal result42 = new BigDecimal(num42);
assertEquals(new BigDecimal("-42"), result42);
正如我們所看到的,我們測試了正值和負值Long
值。調用構造函數後,我們得到了預期的BigDecimal
對象。
4. 使用BigDecimal.valueOf()
方法
BigDecimal
類還提供了一個靜態方法來根據給定的long
值創建BigDecimal
對象: BigDecimal.valuOf()
。
接下來我們看看這個方法的使用方法:
Long num4 = 4L;
BigDecimal result4 = BigDecimal.valueOf(num4);
assertEquals(new BigDecimal("4"), result4);
Long num42 = -42L;
BigDecimal result42 = BigDecimal.valueOf(num42);
assertEquals(new BigDecimal("-42"), result42);
5. 使用哪一個?
我們已經看到了從long
值創建BigDecimal
對象的兩種方法: BigDecimal(long val)
構造函數和靜態方法BigDecimal.valueOf(long val)
。有人可能會問, Long
轉BigDecimal
時選擇哪種方法呢?
讓我們首先回答這個問題:我們應該使用靜態方法而不是構造函數。接下來,我們將了解為什麼靜態方法是更好的選擇。
為了理解這兩種方法之間的區別,讓我們看一下valueOf()
方法的實現:
public static BigDecimal valueOf(long val) {
if (val >= 0L && val < (long)ZERO_THROUGH_TEN.length) {
return ZERO_THROUGH_TEN[(int)val];
} else {
return val != Long.MIN_VALUE ? new BigDecimal((BigInteger)null, val, 0, 0) : new BigDecimal(INFLATED_BIGINT, val, 0, 0);
}
}
如上面的代碼所示,該方法檢查是否給定的long
值在0
到10
之間,它從數組ZERO_THROUGH_TEN.
接下來,讓我們看看ZERO_THROUGH_TEN
數組中的內容:
public class BigDecimal ... {
...
private static final BigDecimal[] ZERO_THROUGH_TEN;
...
static {
ZERO_THROUGH_TEN = new BigDecimal[]{
new BigDecimal(BigInteger.ZERO, 0L, 0, 1),
...
new BigDecimal(BigInteger.valueOf(9L), 9L, 0, 1),
new BigDecimal(BigInteger.TEN, 10L, 0, 2)};
...
...}
}
我們可以看到, ZERO_THROUGH_TEN
是一個static BigDeicmal
數組,它在靜態塊中初始化。因此, BigDeicmal
類將值0
到10
緩存在ZERO_THROUGH_TEN
數組中。
因此,當我們調用BigDecimal.valueOf()
時,如果long
值介於0
和10
之間,則valueOf()
立即為我們提供ZERO_THROUGH_TEN
數組中的緩存對象。否則,它構造一個新的BigDecimal
對象。
接下來我們通過測試來驗證一下:
Long num4 = 4L;
BigDecimal bd4_1 = BigDecimal.valueOf(num4);
BigDecimal bd4_2 = BigDecimal.valueOf(num4);
BigDecimal bd4_3 = BigDecimal.valueOf(num4);
assertSame(bd4_1, bd4_2);
assertSame(bd4_2, bd4_3);
Long num42 = -42L;
BigDecimal bd42_1 = BigDecimal.valueOf(num42);
BigDecimal bd42_2 = BigDecimal.valueOf(num42);
BigDecimal bd42_3 = BigDecimal.valueOf(num42);
assertNotSame(bd42_1, bd42_2);
assertNotSame(bd42_1, bd42_3);
assertNotSame(bd42_2, bd42_3);
正如我們所看到的,我們調用了BigDecimal.valueOf(num4)
三次。該方法返回相同的緩存對象。但是,當long
值不在0
到10
之間時,該方法始終返回一個新對象。
另一方面,每次我們調用構造函數時, BigDecimal
類都會為我們構造一個不同的對象:
Long num4 = 4L;
BigDecimal result1 = new BigDecimal(num4);♡
BigDecimal result2 = new BigDecimal(num4);
BigDecimal result3 = new BigDecimal(num4);
assertNotSame(result1, result2);
assertNotSame(result2, result3);
assertNotSame(result1, result3);
Long num42 = -42L;
BigDecimal bd42_1 = new BigDecimal(num42);
BigDecimal bd42_2 = new BigDecimal(num42);
BigDecimal bd42_3 = new BigDecimal(num42);
assertNotSame(bd42_1, bd42_2);
assertNotSame(bd42_1, bd42_3);
assertNotSame(bd42_2, bd42_3);
六,結論
在本文中,我們學習了將Long
值轉換為BigDecimal
對象的兩種方法。
在實踐中,我們應該在構造函數上使用BigDecimal.valueOf()
,因為如果long
值在0
到10
之間,則valueOf()
可以利用緩存的對象。
與往常一樣,本文中提供的所有代碼片段都可以在 GitHub 上找到。