这几天换租房的位置,好累啊。弄得我写博客的习惯都没有按时完成。之前,我在看String.format的源码时,发现了String.format其实内服是使用了Formatter 类,但是自己对这个类不很了解,于是在网上查找资料,最终解决了问题。这里记录一下。
先看看String.format的源码:
public static String format(String format, Object... args) { return new Formatter().format(format, args).toString(); }
整理一下关于 Formatter 的用法
实例化一个Formatter
StringBuilder builder = new StringBuilder();
//builder 用来存储格式化后的字符串
Formatter formatter = new Formatter(builder, Locale.CHINA);
format 方法,第一个参数是格式字符串,用来格式化后面的一个或多个参数。后面是一个可变参数列表。
public Formatter format(String format, Object ... args) {
return format(l, format, args);
}
格式字符串包含固定文本能够嵌入一个或多个格式说明符。例如:
Calendar calendar = Calendar.getInstance();
String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", calendar);
第一个参数是格式字符串,包含三个格式说明符,%1$tm %1$te,%1$tY
,用来表明后
面的参数 calendar 改怎样被处理以及该插入到输出文本的什么位置。格式化字符串剩余
的部分是固定的文本包括Duke's Birthday: 和其他的空格以及标点符号。
通用类型,字符类型和数字类型的格式说明符语法如下:
%[argument_index$][flags][width][.precision]conversion
argument_index 选项是一个十进制整数,用来只是要被格式化的参数在参数列表中
的位置。第一个参数用“1$”
表示,第二个参数用“2$”
表示,以此类推。
也可以使用另外一种方式表示参数位置,就是使用‘<’,表示使用前一个格式化说明符指向的参数。
//下面两行代码表示都使用第一个参数。c
Calendar c = ...;
String s1 = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
String s2 = String.format("Duke's Birthday: %1$tm %<te,%<tY", c);
flags 选项是一组用来修改输出格式的字符集,flags 合法的取值依赖conversion选项。width 选项是一个非负的整数,表示要写入输出的最少字符数。precision 选项是一个非负的整数,通常用来限制字符数,具体的行为依赖conversion选项。
必选项conversion 是一个字符指示参数应该怎样被格式化。合法的conversion字符取值依赖于要被格式化的参数的数据类型。
用来格式化日期和时间类型的格式说明符语法如下,和上面的语法相比少了精度选项。
%[argument_index$][flags][width]conversion
argument_index ,flags,width 选项和上面的定义一样。必选项conversion 是一个两个字符的序列,第一个字符必须是’t’ or ‘T’,第二个字符用来格式化参数。
没有参数对应的格式说明符具有以下语法:
%[flags][width]conversion
lags,width 选项和上面的定义一样。必选项conversion是一个字符用来指示内容应该如何被插入到输出中。
//没有参数对应格式[argument_index$],默认每一个百分号后面的格式化字符串对应一个参数。
//%tm 格式化 calendar1,%te 格式化 calendar2,%tR 格式化 calendar3
Calendar calendar1 = Calendar.getInstance();
Calendar calendar2 = Calendar.getInstance();
Calendar calendar3 = Calendar.getInstance();
String.format("Duke's Birthday: %tm,%te,%tR", calendar1,calendar2,calendar3)
1:General 可用于任何参数类型
2:Character 可用于代表Unicode字符的基本类型:char, Character, byte, Byte, short,and Short;
2.1 当 isValidCodePoint(int) returns true的时候(比如65 代表'A',97 代表'a'),
这类conversion也可用于int and Integer类型
3:Numeric
3.1:Integral 整型的,可用于java的整型,byte, Byte, short, Short, int and Integer, long, Long, and BigInteger
3.2:Floating Point浮点型 用于java 的浮点型 float, Float, double, Double, and BigDecimal
4:Date/Time 可用于java中能够编码date或者time的类型:long, Long, Calendar, and Date
5:Percent :产生一个文本'%' ('\u0025')
6:Line Separator 换行
下表总结了一些转换字符集的用法
Conversion | 参数分类 | 描述 |
---|---|---|
‘b’,’B’ | general | 如果要被各式话的参数是null,输出结果是false,如果参数是一个boolean或者Boolean类型的数据,输出true或者false,其他情况返回true |
‘h’,’H’ | general | 如果要被各式话的参数是null,输出结果是null,其他情况输出Integer.toHexString(arg.hashCode()) |
’s’,’S’ | general | 如果要被各式话的参数是null,输出null,如果参数实现了Formattable接口(如果要自定义Formatter的‘s’转换说明符的功能,需要实现Formattable接口),那么会调用arg.formatTo方法,除此之外,返回结果是arg.toString() |
‘c’,’C’ | character | 结果是一个Unicode字符 |
‘d’ | integral | 结果是一个十进制整数 |
‘o’ | integral | 结果是一个8进制整数 |
‘x’,’X’ | integral | 结果是一个16进制整数 |
‘e’,’E’ | floating point | 结果是一个用科学计数法表示的十进制数字 |
‘f’ | floating point | 结果是一个十进制数字 |
‘g’,’G’ | floating point | 根据参数的精度和四舍五入后的值来选择使用科学计数法或者十进制格式化 |
‘a’,’A’ | floating point | 结果是一个十进制数字 |
‘f’ | floating point | 结果是一个用基数和指数表示的十六进制浮点数 |
‘t’,’T’ | date/time | 日期和时间转换字符集的第一个字符,下面细说 |
‘%’ | percent | 结果是一个% |
‘n’ | line separator | 结果是一个换行符 |
Date/Time 类型的Conversions,开始第一个字符是’t’或者 ‘T’,然后才能选择下表中的一个。
Conversions | 描述 |
---|---|
‘H’ | 24小时制,结果被格式化成两位数,如果必要以0开头,比如07,(范围00-23) |
‘I’ | 12小时制,结果被格式化成两位数,如果必要以0开头,比如07,(范围01-12) |
‘k’ | 24小时制,范围(0-23) |
‘l’ | 12小时制,范围(1-12)< |