1. 概述
在本教程中,我们将演示使用printf()方法进行格式化的不同示例。
该方法是java.io.PrintStream类的一部分,提供类似于C中的printf()函数的字符串格式化。
2. 语法
我们可以使用以下PrintStream方法之一来格式化输出:
System.out.printf(format, arguments);
System.out.printf(locale, format, arguments);
我们使用format参数指定格式规则,规则以%字符开头。
在深入了解各种格式化规则的细节之前,让我们看一个简单的例子:
System.out.printf("Hello %s!%n", "World");
这将生成以下输出:
Hello World!
如上所示,格式字符串包含纯文本和两个格式规则。第一个规则用于格式化字符串参数。第二个规则在字符串末尾添加一个换行符。
2.1 格式规则
让我们更仔细地看一下格式字符串。它由文字和格式说明符组成,格式说明符按以下顺序包括标志、宽度、精度和转换字符:
%[flags][width][.precision]conversion-character
括号中的说明符是可选的。
在内部,printf()使用java.util.Formatter类来解析格式字符串并生成输出。可以在Formatter Javadoc中找到其他格式字符串选项。
2.2 转换字符
转换字符是必需的,它决定参数的格式。
转换字符仅对某些数据类型有效,以下是一些常见的:
- s格式化字符串
- d格式化十进制整数
- f格式化浮点数
- t格式化日期/时间值
2.3 可选修饰符
[flags]定义了修改输出的标准方法,最常用于格式化整数和浮点数。
[width]指定输出参数的字段宽度,它表示写入输出的最少字符数。
[.precision]指定输出浮点值时的精度位数。此外,我们可以使用它来定义要从String中提取的子字符串的长度。
3. 行分隔符
为了将字符串分成单独的行,我们有一个%n说明符:
System.out.printf("tuyucheng%nline%nterminator");
上面的代码片段将生成以下输出:
tuyucheng
line
terminator
%n分隔符printf()将自动插入主机系统的本机行分隔符。
4. 布尔格式
要格式化布尔值,我们使用%b格式。
根据文档,它的工作方式如下:如果第二个参数为null,则结果为“false”。如果参数是布尔值或Boolean,则结果是String.valueOf(arg)返回的字符串。否则,结果为“true”。
因此,如果我们执行以下操作:
System.out.printf("%b%n", null);
System.out.printf("%B%n", false);
System.out.printf("%B%n", 5.3);
System.out.printf("%b%n", "random text");
然后我们会看到:
false
FALSE
TRUE
true
请注意,我们可以使用%B进行大写格式化。
5. 字符串格式化
要格式化一个简单的字符串,我们将使用%s组合。此外,我们可以将字符串设为大写:
printf("'%s' %n", "tuyucheng");
printf("'%S' %n", "tuyucheng");
这是输出:
'tuyucheng'
'TUYUCHENG'
此外,要指定最小长度,我们可以指定宽度:
printf("'%15s' %n", "tuyucheng");
这输出:
' tuyucheng'
如果我们需要左对齐我们的字符串,我们可以使用–标志:
printf("'%-10s' %n", "tuyucheng");
这是输出:
'tuyucheng '
更重要的是,我们可以通过指定精度来限制输出中的字符数:
System.out.printf("%2.2s", "Hi there!");
%x.ys语法中的第一个x数字是填充,y是字符数。
对于我们这里的示例,输出是Hi。
6. 字符格式化
%c的结果是一个Unicode字符:
System.out.printf("%c%n", 's');
System.out.printf("%C%n", 's');
大写字母C会将结果大写:
s
S
但是如果我们给它一个无效的参数,那么Formatter将抛出IllegalFormatConversionException。
7. 数字格式
7.1 整数格式
printf()方法接受语言中可用的所有整数-byte、short、int、long和BigInteger(如果我们使用%d):
System.out.printf("simple integer: %d%n", 10000L);
在d字符的帮助下,我们将得到以下结果:
simple integer: 10000
如果我们需要用千位分隔符格式化我们的数字,我们可以使用,标志。我们还可以为不同的语言环境格式化我们的结果:
System.out.printf(Locale.US, "%,d %n", 10000);
System.out.printf(Locale.ITALY, "%,d %n", 10000);
正如我们所见,美国的格式与意大利的不同:
10,000
10.000
7.2 float和double格式化
要格式化浮点数,我们需要f格式:
System.out.printf("%f%n", 5.1473);
这将输出:
5.147300
当然,首先想到的是控制精度:
System.out.printf("'%5.2f'%n", 5.1473);
这里我们定义数字的宽度为5,小数部分的长度为2:
' 5.15'
这里我们从数字的开头填充一个空格以支持预定义的宽度。
要以科学记数法输出,我们只需使用e转换字符:
System.out.printf("'%5.2e'%n", 5.1473);
这是我们的结果:
'5.15e+00'
8. 日期和时间格式
对于日期和时间格式,转换字符串是两个字符的序列:t或T字符和转换后缀。
让我们通过示例探索最常见的时间和日期格式后缀字符。
当然,对于更高级的格式化,我们可以使用DateTimeFormatter,它从Java 8开始可用。
8.1 时间格式
首先,让我们看看一些有用的时间格式后缀字符列表:
- H、M、S字符负责从输入Date中提取小时、分钟和秒
- L、N相应地表示以毫秒和纳秒为单位的时间
- p添加am/pm格式
- z打印出时区偏移量
现在,假设我们要打印出Date的时间部分:
Date date = new Date();
System.out.printf("%tT%n", date);
上面的代码与%tT组合生成以下输出:
13:51:15
如果我们需要更详细的格式,我们可以调用不同的时间段:
System.out.printf("hours %tH: minutes %tM: seconds %tS%n", date, date, date);
使用H、M 和S后,我们得到以下结果:
hours 13: minutes 51: seconds 15
但是,多次列出日期是一件痛苦的事情。
或者,为了摆脱多个参数,我们可以使用输入参数的索引引用,在我们的例子中为1$:
System.out.printf("%1$tH:%1$tM:%1$tS %1$tp %1$tL %1$tN %1$tz %n", date);
在这里,我们希望将当前时间、上午/下午、以毫秒和纳秒为单位的时间以及时区偏移量作为输出:
13:51:15 pm 061 061000000 +0400
8.2 日期格式
和时间格式化一样,我们有特殊的格式化字符用于日期格式化:
- A打印出一周中的整天
- d格式化一个月中的两位数日期
- B是完整的月份名称
- m格式化两位数的月份
- Y以四位数输出年份
- y输出年份的最后两位数字
假设我们要显示星期几,然后是月份:
System.out.printf("%1$tA, %1$tB %1$tY %n", date);
然后,使用A、B 和Y,我们将得到以下输出:
Thursday, November 2018
为了让我们的结果全部采用数字格式,我们可以将A、B、Y字母替换为d、m、y:
System.out.printf("%1$td.%1$tm.%1$ty %n", date);
这将生成:
22.11.18
9. 总结
在本文中,我们讨论了如何使用PrintStream#printf方法来格式化输出。我们研究了用于控制常见数据类型输出的不同格式模式。
与往常一样,本教程的完整源代码可在GitHub上获得。