`DecimalFormat` 是 `NumberFormat` 具體實現,用於**數字格式化**(數字 → 字符串)與**解析**(字符串 → 數字),支持自定義模式、本地化、科學記數法、百分比、貨幣等。
DecimalFormat df = (DecimalFormat) DecimalFormat.getInstance(); // 默認 Locale
DecimalFormat df = (DecimalFormat) DecimalFormat.getInstance(Locale.US); // 指定 Locale
DecimalFormat df = new DecimalFormat("###,##0.00"); // 自定義模式
| 符號 | 含義 | 示例 |
|---|---|---|
0 | **數字佔位符**,不足補 0 | `00.00` → `01.23`、`1.2` → `01.20` |
# | **數字佔位符**,不足**不補 0** | `##.##` → `1.23`、`1.2` → `1.2` |
. | 小數點(按 Locale 解析) | `#,##0.00` |
, | 分組分隔符(千分位) | `#,###` → `1,234` |
% | 百分比(乘 100 並加 %) | `##%` → `0.12` → `12%` |
E | 科學記數法 | `0.###E0` → `1234` → `1.234E3` |
; | 分隔正/負/零子模式 | `###;(-###);"Zero"` |
¤ | 貨幣符號(按 Locale) | `¤#,##0.00` → `$1,234.56` |
' | 轉義字面量字符 | `'#'#` → 字面 `#` + 數字 |
DecimalFormat df = (DecimalFormat) DecimalFormat.getInstance();
double d = 1.5555555;
System.out.println(df.format(d)); // 1.556 (默認 3 位小數)
df.setMaximumFractionDigits(5); // 最大小數位
System.out.println(df.format(d)); // 1.55556
df.setMaximumFractionDigits(2);
System.out.println(df.format(d)); // 1.56 (四捨五入)
df.setMinimumFractionDigits(10); // 最小小數位,不足補 0
System.out.println(df.format(d)); // 1.5555555500
df.setMinimumIntegerDigits(3); // 整數部分最小位數
System.out.println(df.format(d)); // 001.56
df.setMaximumIntegerDigits(2); // 整數部分最大位數,超出截取低位
System.out.println(df.format(123.45)); // 23.45
int number = 155566;
System.out.println(df.format(number)); // 155,566 (默認 3 位分組)
df.setGroupingSize(4); // 4 位一組
System.out.println(df.format(number)); // 15,5566
// 自定義分隔符
DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance();
dfs.setDecimalSeparator(';'); // 小數點改為分號
dfs.setGroupingSeparator('a'); // 分組符改為 a
df.setDecimalFormatSymbols(dfs);
System.out.println(df.format(number)); // 15a5566
System.out.println(df.format(11.22)); // 11;22
df.setGroupingUsed(false); // 禁用分組
System.out.println(df.format(number)); // 155566
double a = 1.220, b = 11.22, c = 0.22;
// 百分比:##.##% 不補 0,00.00% 強制兩位
df.applyPattern("##.##%");
System.out.println(df.format(a)); // 122%
System.out.println(df.format(b)); // 1122%
System.out.println(df.format(c)); // 22%
// 固定格式:00.000 強制 2位整數+3位小數,##.### 靈活
df.applyPattern("00.000");
System.out.println(df.format(1.22222222)); // 01.222
df.applyPattern("##.###");
System.out.println(df.format(1.22222222)); // 1.222
df.applyPattern("###.##;(###.##);Zero");
System.out.println(df.format(123.45)); // 123.45
System.out.println(df.format(-123.45)); // (123.45)
System.out.println(df.format(0)); // Zero
NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(Locale.US);
System.out.println(currencyFormat.format(1234.56)); // $1,234.56
// 或 DecimalFormat
DecimalFormat currencyDf = new DecimalFormat("¤#,##0.00");
currencyDf.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.CHINA));
System.out.println(currencyDf.format(1234.56)); // ¥1,234.56
DecimalFormat df = new DecimalFormat("###,##0.00");
try {
Number num = df.parse("1,234.56");
System.out.println(num.doubleValue()); // 1234.56
System.out.println(num.getClass()); // java.lang.Double
} catch (ParseException e) {
e.printStackTrace();
}
DecimalFormat 不是線程安全的! 多線程環境下每個線程創建實例,或使用 `ThreadLocal`、同步塊、或無狀態 `NumberFormat.getInstance()` 後轉型。
// 方案 1:ThreadLocal (高性能)
private static final ThreadLocal DF_THREAD_LOCAL = ThreadLocal.withInitial(
() -> new DecimalFormat("###,##0.00")
);
public static String format(double d) {
return DF_THREAD_LOCAL.get().format(d);
}
// 方案 2:方法內創建 (簡單、無併發壓力)
public static String formatSimple(double d) {
return new DecimalFormat("###,##0.00").format(d);
}
NumberFormat fmt = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
fmt.setMaximumFractionDigits(1);
System.out.println(fmt.format(1234567)); // 1.2M
NumberFormat percentFmt = NumberFormat.getPercentInstance();
percentFmt.setMinimumFractionDigits(2);
System.out.println(percentFmt.format(0.1234)); // 12.34%