System.out.printf() 和 String.format() - 最常用
这是最直接、最简单的方法,类似于 C 语言中的 printf,它使用格式化字符串来定义输出格式。
核心语法:
%[flags][width][.precision]conversion
-
conversion(转换字符): 必须的,指定如何格式化。d: 整数 (decimal)f: 浮点数 (float)e或E: 科学计数法g或G: 通用格式,自动在f和e之间选择s: 字符串 (String)b或B: 布尔值 (Boolean)c或C: 字符 (Character)x或X: 十六进制整数o: 八进制整数
-
width(宽度): 最小字符数,如果数字长度小于此值,则用空格填充(默认右对齐)。 -
.precision(精度):- 对于
f,e,g,表示小数点后保留的位数。 - 对于
s,表示最大字符数。
- 对于
-
flags(标志):- 左对齐(默认右对齐)
- 总是显示正负号
` (空格): 正数前加一个空格,负数前加负号(与+` 互斥)- 添加千位分隔符 (1,000,000)
- 将负数用括号括起来
0: 用零填充(而不是空格)
示例代码
public class NumberFormatting {
public static void main(String[] args) {
double price = 12345.6789;
int quantity = 9876;
double percentage = 0.87654321;
// 1. 基本浮点数格式化
System.out.println("--- 基本浮点数 ---");
System.out.printf("原始值: %f%n", price); // 默认保留6位小数
System.out.printf("保留2位小数: %.2f%n", price);
System.out.printf("保留0位小数: %.0f%n", price); // 会四舍五入
// 2. 整数格式化
System.out.println("\n--- 整数格式化 ---");
System.out.printf("原始值: %d%n", quantity);
System.out.printf("宽度为10,右对齐: %10d%n", quantity);
System.out.printf("宽度为10,左对齐: %-10d%n", quantity);
System.out.printf("总显示正负号: %+d%n", quantity);
System.out.printf("总显示正负号,宽度为10: %+10d%n", quantity);
System.out.printf("千位分隔符: %,d%n", quantity); // 9,876
// 3. 科学计数法
System.out.println("\n--- 科学计数法 ---");
System.out.printf("默认科学计数法: %e%n", price);
System.out.printf("大写E,保留2位小数: %.2E%n", price);
// 4. 通用格式
System.out.println("\n--- 通用格式 ---");
System.out.printf("通用格式g: %g%n", price);
System.out.printf("通用格式G: %G%n", price);
// 5. 组合使用:格式化货币
System.out.println("\n--- 组合使用示例 ---");
System.out.printf("价格: ¥%,.2f%n", price);
System.out.printf("折扣: %d%% (原价: ¥%,.2f)%n", (int)(percentage * 100), price);
// 6. 使用 String.format() 获取格式化后的字符串
System.out.println("\n--- String.format() ---");
String formattedString = String.format("商品数量: %, 件,总价: ¥%,.2f", quantity, price);
System.out.println(formattedString);
}
}
输出结果:
--- 基本浮点数 ---
原始值: 12345.678900
保留2位小数: 12345.68
保留0位小数: 12346
--- 整数格式化 ---
原始值: 9876
宽度为10,右对齐: 9876
宽度为10,左对齐: 9876
总显示正负号: +9876
总显示正负号,宽度为10: +9876
千位分隔符: 9,876
--- 科学计数法 ---
默认科学计数法: 1.234568e+04
大写E,保留2位小数: 1.23E+04
--- 通用格式 ---
通用格式g: 12345.7
通用格式G: 12345.7
--- 组合使用示例 ---
价格: ¥12,345.68
折扣: 88% (原价: ¥12,345.68)
--- String.format() ---
商品数量: 9,876 件,总价: ¥12,345.68
DecimalFormat 类 - 更灵活,用于本地化
java.text.DecimalFormat 是一个功能更强大的类,特别适合需要复杂格式化规则(如本地化货币、百分号、自定义模式)的场景,它使用模式字符串来定义格式。
核心步骤:
import java.text.DecimalFormat;- 创建
DecimalFormat实例,传入模式字符串。 - 调用
format()方法。
示例代码
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
public class DecimalFormatExample {
public static void main(String[] args) {
double number = 1234567.891;
int integer = 987654321;
// 1. 基本模式
System.out.println("--- 基本模式 ---");
DecimalFormat df1 = new DecimalFormat("###,###.##"); // 任意数字,千位分隔,2位小数
System.out.println(df1.format(number)); // 1,234,567.89
DecimalFormat df2 = new DecimalFormat("000,000.000"); // 固定宽度,不足补0
System.out.println(df2.format(number)); // 1,234,567.891
// 2. 百分比模式
System.out.println("\n--- 百分比模式 ---");
double percentage = 0.789;
DecimalFormat percentFormat = new DecimalFormat("#0.00%");
System.out.println(percentFormat.format(percentage)); // 78.90%
// 3. 货币模式
System.out.println("\n--- 货币模式 ---");
// 使用 NumberFormat 的工厂方法获取特定地区的货币格式
NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(Locale.CHINA);
System.out.println(currencyFormat.format(number)); // ¥1,234,567.89
NumberFormat currencyFormatUS = NumberFormat.getCurrencyInstance(Locale.US);
System.out.println(currencyFormatUS.format(number)); // $1,234,567.89
// 4. 科学计数法
System.out.println("\n--- 科学计数法 ---");
DecimalFormat scientificFormat = new DecimalFormat("0.###E0");
System.out.println(scientificFormat.format(number)); // 1.235E6
// 5. 自定义模式(负数显示为红色括号,但控制台不支持颜色,这里用括号代替)
System.out.println("\n--- 自定义模式 ---");
double profit = 15000;
double loss = -5000;
DecimalFormat profitLossFormat = new DecimalFormat("###,###.00;###,###.00"); // 分号分隔正负格式
System.out.println("利润: " + profitLossFormat.format(profit)); // 利润: 15,000.00
System.out.println("亏损: " + profitLossFormat.format(loss)); // 亏损: 5,000.00 (注意,这里只是格式,没有括号)
// 更精确的自定义
DecimalFormat customFormat = new DecimalFormat("#,##0.00;(#,##0.00)");
System.out.println("亏损(自定义): " + customFormat.format(loss)); // 亏损(自定义): (5,000.00)
}
}
输出结果:
--- 基本模式 ---
1,234,567.89
1,234,567.891
--- 百分比模式 ---
78.90%
--- 货币模式 ---
¥1,234,567.89
$1,234,567.89
--- 科学计数法 ---
1.235E6
--- 自定义模式 ---
利润: 15,000.00
亏损: 5,000.00
亏损(自定义): (5,000.00)
NumberFormat 类 - 国际化友好
java.text.NumberFormat 是一个抽象基类,它提供了很多静态工厂方法来获取不同风格的格式化器,特别适合处理国际化(i18n)问题。
NumberFormat.getInstance(): 获取通用数字格式。NumberFormat.getCurrencyInstance(): 获取货币格式。NumberFormat.getPercentInstance(): 获取百分比格式。NumberFormat.getIntegerInstance(): 获取整数格式。
它内部会根据 Locale(地区)自动使用正确的千位分隔符、小数点符号和货币符号。
示例代码
import java.text.NumberFormat;
import java.util.Locale;
public class NumberFormatExample {
public static void main(String[] args) {
double number = 1234567.89;
double percentage = 0.5678;
// 1. 通用数字格式
System.out.println("--- 通用数字格式 ---");
NumberFormat generalFormat = NumberFormat.getInstance();
System.out.println("默认地区: " + generalFormat.format(number)); // 1,234,567.89
NumberFormat germanFormat = NumberFormat.getInstance(Locale.GERMANY);
System.out.println("德国地区: " + germanFormat.format(number)); // 1.234.567,89
// 2. 货币格式
System.out.println("\n--- 货币格式 ---");
NumberFormat currencyFormatCN = NumberFormat.getCurrencyInstance(Locale.CHINA);
System.out.println("中国货币: " + currencyFormatCN.format(number)); // ¥1,234,567.89
NumberFormat currencyFormatUS = NumberFormat.getCurrencyInstance(Locale.US);
System.out.println("美国货币: " + currencyFormatUS.format(number)); // $1,234,567.89
NumberFormat currencyFormatJP = NumberFormat.getCurrencyInstance(Locale.JAPAN);
System.out.println("日本货币: " + currencyFormatJP.format(number)); // ¥1,234,568
// 3. 百分比格式
System.out.println("\n--- 百分比格式 ---");
NumberFormat percentFormat = NumberFormat.getPercentInstance();
System.out.println("默认百分比: " + percentFormat.format(percentage)); // 56.78%
NumberFormat frenchPercentFormat = NumberFormat.getPercentInstance(Locale.FRANCE);
System.out.println("法国百分比: " + frenchPercentFormat.format(percentage)); // 56,78 %
// 4. 整数格式
System.out.println("\n--- 整数格式 ---");
NumberFormat integerFormat = NumberFormat.getIntegerInstance();
System.out.println("整数格式: " + integerFormat.format(number)); // 1,234,568
}
}
输出结果:
--- 通用数字格式 ---
默认地区: 1,234,567.89
德国地区: 1.234.567,89
--- 货币格式 ---
中国货币: ¥1,234,567.89
美国货币: $1,234,567.89
日本货币: ¥1,234,568
--- 百分比格式 ---
默认百分比: 56.78%
法国百分比: 56,78 %
--- 整数格式 ---
整数格式: 1,234,568
总结与选择建议
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
printf / String.format |
语法简洁,直接嵌入代码 | 功能相对固定,国际化支持弱 | 简单的控制台输出、日志、快速格式化字符串。 |
DecimalFormat |
功能强大,模式非常灵活(如自定义符号、科学计数法) | 需要创建对象,模式字符串学习成本稍高 | 需要复杂、非标准的数字格式,如特定报表格式、自定义百分比显示。 |
NumberFormat |
国际化支持最好,自动适配地区 | 功能相对 DecimalFormat 较弱,灵活性低 |
需要显示给用户的、面向国际化的界面,如货币、百分比、通用数字。 |
简单选择指南:
-
只是想在控制台打印一下,或者快速生成一个格式化的字符串?
- 用
System.out.printf()或String.format(),这是最简单直接的方式。
- 用
-
需要处理货币、百分比,并且希望程序在不同国家/地区都能正确显示?
- 用
NumberFormat,这是国际化应用的最佳选择。
- 用
-
需要非常自定义的格式, 或者特定格式的科学计数法?
- 用
DecimalFormat,它提供了最大的控制力。
- 用
