引言
在Java中,数字格式化是一项非常常见且重要的功能,它允许开发者以特定的格式展示数字,无论是整数、浮点数、百分比还是货币值等。Java提供了多种方式来格式化数字,包括使用DecimalFormat类、String.format()方法、NumberFormat类及其子类(如DecimalFormat、CurrencyFormat和PercentFormat),以及从Java 8开始引入的String.joined()方法和java.time.format.DateTimeFormatter(虽然主要用于日期和时间格式化,但这里主要关注数字格式化)。下面是对这些方法的总结:
一、使用String.format()
String.format()方法允许你创建格式化的字符串,其中可以包含数字的格式化表示。这个方法背后的格式化语法与C语言的printf非常相似。
1. 格式说明符
格式说明符以 % 符号开头,后面跟着一个或多个字符,用于指定如何格式化相应的参数。以下是一些常见的格式说明符:
- %d 或 %i:用于整数。
- %f:用于浮点数(默认保留六位小数)。
- %.nf:用于浮点数,n 表示小数点后的位数。
- %e 或 %E:用于科学计数法表示的浮点数。
2. 示例
public class StringFormatExample {
public static void main(String[] args) {
double value = 123456789.123;
String formatted = String.format("%.2f", value);
System.out.println(formatted); // 保留两位小数,输出:123456789.12
}
}
二、 使用NumberFormat及其子类
NumberFormat是一个抽象类,提供了格式化和解析数字的接口。NumberFormat的getNumberInstance()方法可以返回默认的NumberFormat实例,它适合用于格式化数字、货币和百分比等。
- 货币格式化:使用NumberFormat.getCurrencyInstance()
- 百分比格式化:使用NumberFormat.getPercentInstance()
import java.text.NumberFormat;
public class NumberFormatExample {
public static void main(String[] args) {
NumberFormat currencyFormat = NumberFormat.getCurrencyInstance();
NumberFormat percentFormat = NumberFormat.getPercentInstance();
double amount = 1234567.89;
double percentage = 0.12345;
System.out.println(currencyFormat.format(amount)); // 输出依赖于Locale,例如:$1,234,567.89
System.out.println(percentFormat.format(percentage)); // 输出:12%
}
}
三、使用DecimalFormat
DecimalFormat是NumberFormat的一个具体子类,它允许你通过模式字符串来定义数字格式。这个类非常灵活,可以定义小数点后的位数、分组分隔符、正负号样式等。
1. 基础概念
DecimalFormat 通过模式字符串来控制数字的格式化方式。模式字符串由以下元素组成:
- 0:表示至少显示一个数字,如果不足则用0填充。
- #:表示数字存在则显示,不存在则不显示。
- ,:分组分隔符。
- .:小数点分隔符。
- E:科学记数法中的指数部分。
- ;:分隔正数和负数的格式。
2. 模式字符串
模式字符串由两部分组成:正数模式和负数模式,中间用分号(;)分隔。如果没有提供负数模式,那么负数将使用正数模式,并在其前面添加负号。
示例
以下是一些常见的模式示例及其输出结果:
- ###,###.##:对于数字 123456.789,输出为 123,456.789。
- 000000.000:对于数字 123.78,输出为 000123.780。
- $###,###.###:对于数字 12345.67,输出为 $12,345.67。
3. Locale 敏感格式化
DecimalFormat 可以根据不同 Locale 的规则进行格式化。例如,使用以下代码可以获取特定 Locale 的 NumberFormat 实例:
NumberFormat nf = NumberFormat.getInstance(Locale.FRANCE);
DecimalFormat df = (DecimalFormat) nf;
df.applyPattern("###,###.###");
更改格式符号
可以使用 DecimalFormatSymbols 类来更改格式化输出中的符号,例如:
DecimalFormatSymbols symbols = new DecimalFormatSymbols();
symbols.setDecimalSeparator('|');
symbols.setGroupingSeparator('^');
DecimalFormat df = new DecimalFormat("#,##0.###", symbols);
4. 实用技巧
使用 0.## 模式可以保留最多两位小数,如果数字小于1则不显示前导零。
使用 0.00 模式可以总是显示两位小数,如果数字小于1则显示前导零。
使用 #.##% 模式可以将数字格式化为百分比形式。
5.完整示例
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
public class DecimalFormatDemo {
public static void main(String[] args) {
// 基本格式化
DecimalFormat df1 = new DecimalFormat("#.00");
System.out.println(df1.format(0.1)); // 输出: .10
// 自定义 Locale
Locale customLocale = new Locale("de", "DE");
DecimalFormat df2 = (DecimalFormat) NumberFormat.getInstance(customLocale);
df2.applyPattern("#.##%");
System.out.println(df2.format(0.25)); // 输出: 25.00%
// 自定义格式符号
DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.US);
symbols.setDecimalSeparator('|');
symbols.setGroupingSeparator('^');
DecimalFormat df3 = new DecimalFormat("#,##0.###", symbols);
df3.setGroupingSize(4);
System.out.println(df3.format(12345.678)); // 输出: 1^2345|678
}
}