一、干嘛的?(作用)
在java中,所有新的格式化功能都有formatter类处理。可以将formatter看作一个翻译器,它将你的格式化字符串与数据翻译成需要的结果。比如很多地方格式输出都有用到,像我们在超市购物付款时候打印的购物小票啊,所以还是很实用的。
二、籍贯(所在库)
java中的Formatter类位于java.util.Formatter中,所以需要用到的时候只要import进来就可以用了。注意,请选择1.5及以上版本的编译器,否则会出现“The method format(String, Object[]) in the type Formatter is not applicable for the arguments (String, char)”这个错误。
三、家庭住址(如何使用)
如下面代码所示:创建一个Formatter类,需要向构造函数传递你最终想要把结果输出的位置。例如:System.out,或者是File等等。
import java.util.*;
public class Conversion {
public static void main(String[] args) {
//new Formatter(你想要字符串格式化输出的位置,可以使System.out,可以使另外一个String,也可以使一个文件等)
Formatter formatterOut = new Formatter(System.out);
formatterOut.format("%s", "I am a formatter test");
}
}
//输出结果:I am a formatter test
四、性格(格式化输出说明)
这一节,要说的是format的参数该怎么写。我们把format的第一个参数称为Format String,把第二个参数及以后的参数称为argument list。如下面的代码所示,Format String指的是Duke’s Birthday: %1$tm %1$te,%1$tY,而argument list指的是c。
Calendar c = ...;
String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
下面我们就Format String的语法作下说明啦!Format String的格式如下:
%[argument_index$][flags][width][.precision]conversion
字段 | 说明 |
argument_index | 需要将参数列表中第几个参数进行格式化 |
flags | 一些特殊的格式,比如‘-’代表向左对齐 |
width | 输出的最小的宽度,适用于所有的参数类型 |
[.precision] | 参数为String,则表示打印String输出字符的最大数量;参数为float,则表示小数点最大位数。不使用于int |
conversion | 接受的参数类型,如s代表后面接String类型的参数;d代表接int型的参数 |
下面,我们举一些例子来说明上面表格的意思吧,有例子就很清楚了。
import java.util.*;
public class Receipt {
private double total = 0;
private Formatter f = new Formatter(System.out);
public void printTitle() {
Calendar c = new GregorianCalendar();
//参数说明:
//"%1$" 2为argument_index,说明这个格式作用于参数列表中第1个参数c;
//"-" 为flag,表示向左对齐;
//"15"为width,表示宽度最少为15;
//"tm"为convention,表示输出日期中的month; "ty",表示输出日期中的year, "te",表示输出日期中的day.
f.format("Birthday %1$-15tm %1$te,%1$tY\n", c);
f.format("%-15s %5s %10s\n", "Item", "Qty", "Price");
f.format("%-15s %5s %10s\n", "----", "---", "-----");
}
public void print(String name, int qty, double price) {
f.format("%-15.15s %5d %10.2f\n", name, qty, price);
total += price;
}
public void printTotal() {
f.format("%-15s %5s %10.2f\n", "Tax", "", total*0.06);
f.format("%-15s %5s %10s\n", "", "", "-----");
f.format("%-15s %5s %10.2f\n", "Total", "",
total * 1.06);
System.out.println("我是来打酱油的,为了说明argument_index和precision");
//参数说明:
//"%2$" 2为argument_index,说明这个格式作用于参数列表中第二个参数”456“;
//"-" 为flag,表示向左对齐;
//"5"为width,表示宽度最少为5;
//".2"为precision,作用于String参数,表示等下最多输出String参数中的2位;
//"s"为convention,表示参数列表中只接受String类型的参数
f.format("%2$-5.2s %1$2s", "123", "456");
}
public static void main(String[] args) {
Receipt receipt = new Receipt();
receipt.printTitle();
receipt.print("Lao gan ma", 4, 4.25);
receipt.print("gua zi", 3, 5.1);
receipt.print("pi jiu he zha ji", 1, 14.29);
receipt.printTotal();
}
}
程序输出结果
Birthday 12 4,2014
Item Qty Price
---- --- -----
Lao gan ma 4 4.25
gua zi 3 5.10
pi jiu he zha j 1 14.29
Tax 1.42
-----
Total 25.06
我是来打酱油的,为了说明argument_index和precision
45 123
五、(性格具体啥样儿的啊?)附录
1. convention详细说明
‘b’, ‘B’ | 常规 | 如果参数 arg 为 null,则结果为 “false”。如果arg 是一个 boolean 值或 Boolean ,则结果为 String.valueOf() 返回的字符串。否则结果为 “true”。 |
‘h’, ‘H’ | 常规 | 如果参数 arg 为 null,则结果为 “null”。否则,结果为调用Integer.toHexString(arg.hashCode()) 得到的结果。 |
‘s’, ‘S’ | 常规 | 如果参数 arg 为 null,则结果为 “null”。如果arg 实现 Formattable ,则调用arg.formatTo 。否则,结果为调用 arg.toString() 得到的结果。 |
‘c’, ‘C’ | 字符 | 结果是一个 Unicode 字符 |
‘d’ | 整数 | 结果被格式化为十进制整数 |
‘o’ | 整数 | 结果被格式化为八进制整数 |
‘x’, ‘X’ | 整数 | 结果被格式化为十六进制整数 |
‘e’, ‘E’ | 浮点 | 结果被格式化为用计算机科学记数法表示的十进制数 |
‘f’ | 浮点 | 结果被格式化为十进制数 |
‘g’, ‘G’ | 浮点 | 根据精度和舍入运算后的值,使用计算机科学记数形式或十进制格式对结果进行格式化。 |
‘a’, ‘A’ | 浮点 | 结果被格式化为带有效位数和指数的十六进制浮点数 |
‘t’, ‘T’ | 日期/时间 | 日期和时间转换字符的前缀。请参阅日期/时间转换。 |
‘%’ | 百分比 | 结果为字面值 ‘%’ (‘\u0025’) |
‘n’ | 行分隔符 | 结果为特定于平台的行分隔符 |
任何未明确定义为转换的字符都是非法字符,并且都被保留,以供将来扩展使用。
日期和时间
以下日期和时间转换的后缀字符是为 ‘t’ 和 ‘T’ 转换定义的。这些类型相似于但不完全等同于那些由 GNUdate 和 POSIX strftime(3c) 定义的类型。提供其他转换类型是为了访问特定于 Java 的功能(如将 ‘L’ 用作秒中的毫秒)。
以下转换字符用来格式化时间:
‘H’ | 24 小时制的小时,被格式化为必要时带前导零的两位数,即 00 – 23。 |
‘I’ | 12 小时制的小时,被格式化为必要时带前导零的两位数,即 01 – 12。 |
‘k’ | 24 小时制的小时,即 0 – 23。 |
‘l’ | 12 小时制的小时,即 1 – 12。 |
‘M’ | 小时中的分钟,被格式化为必要时带前导零的两位数,即 00 – 59。 |
‘S’ | 分钟中的秒,被格式化为必要时带前导零的两位数,即 00 – 60 (”60″ 是支持闰秒所需的一个特殊值)。 |
‘L’ | 秒中的毫秒,被格式化为必要时带前导零的三位数,即 000 – 999。 |
‘N’ | 秒中的毫微秒,被格式化为必要时带前导零的九位数,即 000000000 – 999999999。 |
‘p’ | 特定于语言环境的 上午或下午 标记以小写形式表示,例如 “am” 或 “pm”。使用转换前缀’T’ 可以强行将此输出转换为大写形式。 |
‘z’ | 相对于 GMT 的 RFC 822 格式的数字时区偏移量,例如 -0800。 |
‘Z’ | 表示时区缩写形式的字符串。Formatter 的语言环境将取代参数的语言环境(如果有)。 |
‘s’ | 自协调世界时 (UTC) 1970 年 1 月 1 日 00:00:00 至现在所经过的秒数,即Long.MIN_VALUE/1000 与 Long.MAX_VALUE/1000 之间的差值。 |
‘Q’ | 自协调世界时 (UTC) 1970 年 1 月 1 日 00:00:00 至现在所经过的毫秒数,即Long.MIN_VALUE 与 Long.MAX_VALUE 之间的差值。 |
以下转换字符用来格式化日期:
‘B’ | 特定于语言环境的月份全称,例如 “January” 和 “February”。 |
‘b’ | 特定于语言环境的月份简称,例如 “Jan” 和 “Feb”。 |
‘h’ | 与 ‘b’ 相同。 |
‘A’ | 特定于语言环境的星期几全称,例如 “Sunday” 和 “Monday” |
‘a’ | 特定于语言环境的星期几简称,例如 “Sun” 和 “Mon” |
‘C’ | 除以 100 的四位数表示的年份,被格式化为必要时带前导零的两位数,即 00 – 99 |
‘Y’ | 年份,被格式化为必要时带前导零的四位数(至少),例如,0092 等于格里高利历的92 CE。 |
‘y’ | 年份的最后两位数,被格式化为必要时带前导零的两位数,即 00 – 99。 |
‘j’ | 一年中的天数,被格式化为必要时带前导零的三位数,例如,对于格里高利历是 001 – 366。 |
‘m’ | 月份,被格式化为必要时带前导零的两位数,即 01 – 13。 |
‘d’ | 一个月中的天数,被格式化为必要时带前导零两位数,即 01 – 31 |
‘e’ | 一个月中的天数,被格式化为两位数,即 1 – 31。 |
以下转换字符用于格式化常见的日期/时间组合。
‘R’ | 24 小时制的时间,被格式化为 “%tH:%tM” |
‘T’ | 24 小时制的时间,被格式化为 “%tH:%tM:%tS”。 |
‘r’ | 12 小时制的时间,被格式化为 “%tI:%tM:%tS %Tp”。上午或下午标记 (‘%Tp’) 的位置可能与语言环境有关。 |
‘D’ | 日期,被格式化为 “%tm/%td/%ty”。 |
‘F’ | ISO 8601 格式的完整日期,被格式化为”%tY-%tm-%td”。 |
‘c’ | 日期和时间,被格式化为 “%ta %tb %td %tT %tZ %tY”,例如”Sun Jul 20 16:17:00 EDT 1969″。 |
2.flag详细说明
下表总结了受支持的标志。y 表示该标志受指示参数类型支持。
标志 | 常规 | 字符 | 整数 | 浮点 | 日期/时间 | 说明 |
---|---|---|---|---|---|---|
‘-‘ | y | y | y | y | y | 结果将是左对齐的。 |
‘#’ | y1 | – | y3 | y | – | 结果应该使用依赖于转换类型的替换形式 |
‘+’ | – | – | y4 | y | – | 结果总是包括一个符号 |
‘ ‘ | – | – | y4 | y | – | 对于正值,结果中将包括一个前导空格 |
‘0’ | – | – | y | y | – | 结果将用零来填充 |
‘,’ | – | – | y2 | y5 | – | 结果将包括特定于语言环境的组分隔符 |
‘(‘ | – | – | y4 | y5 | – | 结果将是用圆括号括起来的负数 |
1 取决于 Formattable
的定义。
2 只适用于 ‘d’ 转换。
3 只适用于 ‘o’、’x’ 和 ‘X’ 转换。
4 对 BigInteger
应用 ‘d’、’o’、’x’ 和 ‘X’ 转换时,或者对byte 及 Byte
、short 及Short
、int 及Integer
、long 及Long
分别应用 ‘d’ 转换时适用。
5 只适用于 ‘e’、’E’、’f’、’g’ 和’G’ 转换。
任何未显式定义为标志的字符都是非法字符,并且都被保留,以供扩展使用。
六、致谢
本文后面部分的详细说明参考网路上spec的中文翻译,在此表示感谢。如有不足之处,敬请指出。