Java 的格式化字符串
Java 的格式化字符串
一、格式化 Formatter
- 参考了 C 语言的
printf()函数,但 Java 的格式化会更严格一些 - 同时定制化增加了 Java 语言的一些特性,使得格式化更适用于 Java 语言
二、格式化方法
2.1 使用 Formatter 实例
1 | Formatter formatter = new Formatter(); |
2.2 使用 System 中的方法
1 | // out |
2.3 使用 String 中的静态方法
1 | String s = String.format("Duke's Birthday: %1$tb %1$te, %1$tY", c); |
2.4 格式化方法要素
所有的格式化方法都有 2 个要素:
format string:格式化字符串argument list:参数列表
比如:
1 | String s = String.format("%4$2s %3$2s %2$2s %1$2s", "a", "b", "c", "d"); |
其中,
%4$2s %3$2s %2$2s %1$2s是格式化字符串"a", "b", "c", "d"是参数列表
格式化字符串的写法是有固定语法的,不能随意写。
三、格式化语法
参数类型可以分为几类:
- 通用:比如字符串
- 字符:比如字母
- 数值:比如整数和浮点数
- 日期时间:比如年月日,时分秒
- 无参类型:比如换行
对于不同的参数数据类型,格式化语法会稍微有点不一样。
3.1 通用、字符、数值
语法格式:
1 | %[argument_index$][flags][width][.precision]conversion |
argument_index:参数索引,指定使用第几个参数,1$表示第1个参数,2$表示第2个参数flags:标志,用于调整参数输出的格式,比如左对齐,前缀补零等width:输出宽度,用于指定参数输出的最小字符数量precision:对于数值型参数,用于指定精度;对于某些类型,用于表示输出的最大字符数量conversion:转换符,单个字母,用于表示参数如何被格式化
举个例子:
1 | ("%4$2s", "a", "b", "c", "d") --> " d" |
3.2 日期、时间
语法格式:
1 | %[argument_index$][flags][width]conversion |
argument_index、flags、width和上面的通用型含义一样conversion:转换符,2 个字母,第一个字母是t或T,用于表示参数如何被格式化
举个例子:
1 | ("%1$tY", new Date()) --> 2023 |
3.3 无参类型
语法格式:
1 | %[flags][width]conversion |
flags、width和上面的通用型含义一样conversion:表示输出的内容,没有参数,不是占位符了
举个例子:
1 | ("%d%%", 50) --> "50%" |
四、转换符(conversion)
4.1 转换符分类
| 类型 | 应用范围 | 适用参数类型 |
|---|---|---|
| 通用型 | 所有参数类型 | |
| 字符型 | 可应用于 Unicode 字符展示的基本类型 | 包括 char、Character、byte、Byte、short、Short还有可能应用于 int、Integer 类型(满足 Character.isValidCodePoint) |
| 数值型 | 可分为整型和浮点型 | 整型包括 byte、Byte、short、Short、int、Integer、long、Long、BigInteger浮点型包括 float、Float、double、Double、BigDecimal |
| 日期时间 | 可应用于日期和时间 | 包括 long、Long、Calendar、Date、TemporalAccessor |
| 百分比 | 特定字面量 % |
只有 % |
| 换行符 | 特定平台的换行符 | 比如 \n、\r\n |
4.2 转换符汇总
| 转换符 | 分类类型 | 描述 |
|---|---|---|
| b/B | 通用型 | 布尔值。 null 的结果是 false 布尔参数时等于 String.valueOf(arg) 非布尔参数时等于 true |
| h/H | 通用型 | 哈希值。 结果等于 Integer.toHexString(arg.hashCode()) |
| s/S | 通用型 | 字符串。 如果参数实现了 Formattable 接口,那么输出就是 arg.formatTo() 的结果 否则输出等于 arg.toString() |
| c/C | 字符型 | Unicode 字符 |
| d | 整型 | 整数 |
| o | 整型 | 八进制整数 |
| x/X | 整型 | 十六进制整数 |
| e/E | 浮点型 | 科学计数法 |
| f | 浮点型 | 小数 |
| g/G | 浮点型 | 小数或者科学计数法,根据数据的实际情况动态决定使用哪种 |
| a/A | 浮点型 | 十六进制浮点数,带有效数和指数 |
| t/T | 日期时间 | 日期时间转换符的固定前缀 |
| % | 百分比 | 字面量 % |
| n | 换行符 | 特定平台的换行符 |
转换符大小写的格式化作用相同,仅仅是输出结果的大小写不一样。
1 | /* 布尔值 b/B */ |
4.3 日期转换符
| 转换符 | 描述 | 示例 |
|---|---|---|
| Y | 4位数的年份 | 0092 |
| y | 2位数的年份 | 范围是 00 - 99 |
| B | 本地化的月份全称 | “January”、”February” |
| b | 本地化的月份简称 | “Jan”、”Feb” |
| h | 和 b 一样 | |
| m | 2位数的月份,从01开始 | 范围是 01 - 13 |
| A | 本地化的周全称 | “Sunday”、”Monday” |
| a | 本地化的周简称 | “Sun”、”Mon” |
| d | 2位数的每月天数 | 范围是 01 - 31 |
| e | 每月天数 | 范围是 1 - 31 |
1 | System.out.printf("year: %ty, %tY", new Date(), new Date()); |
4.4 时间转换符
| 转换符 | 描述 |
|---|---|
| H | 小时,24小时制,2位数,范围是 00 - 23 |
| I(i的大写) | 小时,12小时制,2位数,范围是 01 - 12 |
| k | 小时,24小时制,范围是 0 - 23 |
| l(L的小写) | 小时,12小时制,范围是 1 - 12 |
| M | 分钟,2位数,范围是 00 - 59 |
| S | 秒,2位数,范围是 00 - 60,60专门用于支持闰秒 |
| L | 毫秒,3位数,范围是 000 -999 |
| N | 纳秒,9位数,范围是 000000000 - 999999999 |
| s | 从 1970/01/01 00:00:00 开始的秒数,范围是 Long.MIN_VALUE/1000 - Long.MAX_VALUE/1000 |
| Q | 从 1970/01/01 00:00:00 开始的毫秒数,范围是 Long.MIN_VALUE - Long.MAX_VALUE |
| p | 特定语言的上午或者下午,比如 am,pm |
1 | System.out.printf("hour: %tH, %tI, %tk, %tl", date, date, date, date); |
上面是比较细的转换符,直接用的话写起来比较麻烦。
而且日期时间的输出还是很常用的,所以还提供了一些时间转换符的快捷方式:
| 转换符 | 描述 | 示例 |
|---|---|---|
| R | 表示24小制时分:%tH:%tM | 范围是 00:00 - 23:59 |
| T | 表示24小制时分秒:%tH:%tM:%tS | 范围是 00:00:00 - 23:59:59 |
| D | 表示日期的月日年:%tm/%td/%ty | 比如 01/06/23 |
| F | 表示日期的年月日:%tY-%tm-%td | 比如 2023-01-06 |
| c | 完整的时间日期:%ta %tb %td %tT %tZ %tY | 比如 Sun Jul 20 16:17:00 EDT 1969 |
1 | System.out.printf("HH:MM: %tR", new Date()); |
时间转换符的快捷方式就是用简单的1个字符替代多个转换符,简化代码,相当于缩写。
五、标志位(flags)
标志位用于对输出格式进行一些调整。
| 标志 | 描述 | 示例 | 结果 |
|---|---|---|---|
| - | 左对齐 | (“^%-5d^”, 15) | ^15 ^ |
| # | 如果是浮点数则包含小数点,如果是16进制或8进制则添加0x或0 | (“%#x”, 99) | 0x63 |
| + | 给数值加上符号位,正数前加+,负数前加- | (“%+d”, 99) | +99 |
| 空格 | 在整数之前添加指定数量的空格 | (“^% 4d^”, 99) | ^ 99^ |
| 0 | 在数字前面补0 | (“%04d”, 99) | 0099 |
| , | 以“,”对数字分组 | (“%,d”, 999999999) | 999,999,999 |
| ( | 使用括号包含负数 | (“%(f”, -99.99) | (99.99) |
1 | System.out.printf("left-justified: ^%5d^, ^%-5d^", 99, 99); |
六、宽度(width)
宽度的含义:
- 表示输出字符数量的最小值
- 类型是整数,范围是 1 - Integer.MAX_VALUE
1 | System.out.printf("width: ^%4d^", 99); |
因为输出字符数量最小是 4,因此在 99 之前补了2个空格,所以 ("^%4d^", 99) 的结果是 ^ 99^。
七、精度(precision)
精度对于不同类型的含义:
- 对于通用型,精度表示输出字符数量的最大值
- 对于浮点型,精度表示小数点后面的数字个数
- 对于字符型、整型、日期时间、百分比、换行符等,精度不支持
1 | System.out.printf("general: %.6s", "123456789"); |
参考
java.util.Formatter
https://blog.csdn.net/lonely_fireworks/article/details/7962171/
Java 的格式化字符串